/**
  * perform_atomic_semop - Perform (if possible) a semaphore operation
  * @sma: semaphore array
- * @sops: array with operations that should be checked
- * @nsops: number of operations
- * @un: undo array
- * @pid: pid that did the change
+ * @q: struct sem_queue that describes the operation
  *
  * Returns 0 if the operation was possible.
  * Returns 1 if the operation is impossible, the caller must sleep.
  * Negative values are error codes.
  */
-static int perform_atomic_semop(struct sem_array *sma, struct sembuf *sops,
-                            int nsops, struct sem_undo *un, int pid)
+static int perform_atomic_semop(struct sem_array *sma, struct sem_queue *q)
 {
-       int result, sem_op;
+       int result, sem_op, nsops, pid;
        struct sembuf *sop;
        struct sem *curr;
+       struct sembuf *sops;
+       struct sem_undo *un;
+
+       sops = q->sops;
+       nsops = q->nsops;
+       un = q->undo;
 
        for (sop = sops; sop < sops + nsops; sop++) {
                curr = sma->sem_base + sop->sem_num;
        }
 
        sop--;
+       pid = q->pid;
        while (sop >= sops) {
                sma->sem_base[sop->sem_num].sempid = pid;
                sop--;
                q = container_of(walk, struct sem_queue, list);
                walk = walk->next;
 
-               error = perform_atomic_semop(sma, q->sops, q->nsops,
-                                                q->undo, q->pid);
+               error = perform_atomic_semop(sma, q);
 
                if (error <= 0) {
                        /* operation completed, remove from queue & wakeup */
                if (semnum != -1 && sma->sem_base[semnum].semval == 0)
                        break;
 
-               error = perform_atomic_semop(sma, q->sops, q->nsops,
-                                        q->undo, q->pid);
+               error = perform_atomic_semop(sma, q);
 
                /* Does q->sleeper still need to sleep? */
                if (error > 0)
        if (un && un->semid == -1)
                goto out_unlock_free;
 
-       error = perform_atomic_semop(sma, sops, nsops, un,
-                                       task_tgid_vnr(current));
+       queue.sops = sops;
+       queue.nsops = nsops;
+       queue.undo = un;
+       queue.pid = task_tgid_vnr(current);
+       queue.alter = alter;
+
+       error = perform_atomic_semop(sma, &queue);
        if (error == 0) {
                /* If the operation was successful, then do
                 * the required updates.
         * task into the pending queue and go to sleep.
         */
 
-       queue.sops = sops;
-       queue.nsops = nsops;
-       queue.undo = un;
-       queue.pid = task_tgid_vnr(current);
-       queue.alter = alter;
-
        if (nsops == 1) {
                struct sem *curr;
                curr = &sma->sem_base[sops->sem_num];