Merge tag 'stable/for-linus-3.10-rc3-tag' of git://git.kernel.org/pub/scm/linux/kerne...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / ipc / sem.c
index a7e40ed8a07674fd0493c1495a012a09759d835b..70480a3aa69891b6ebc6c998e2202c3197a443ec 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -752,19 +752,29 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop
                        int otime, struct list_head *pt)
 {
        int i;
+       int progress;
 
-       if (sma->complex_count || sops == NULL) {
-               if (update_queue(sma, -1, pt))
+       progress = 1;
+retry_global:
+       if (sma->complex_count) {
+               if (update_queue(sma, -1, pt)) {
+                       progress = 1;
                        otime = 1;
+                       sops = NULL;
+               }
        }
+       if (!progress)
+               goto done;
 
        if (!sops) {
                /* No semops; something special is going on. */
                for (i = 0; i < sma->sem_nsems; i++) {
-                       if (update_queue(sma, i, pt))
+                       if (update_queue(sma, i, pt)) {
                                otime = 1;
+                               progress = 1;
+                       }
                }
-               goto done;
+               goto done_checkretry;
        }
 
        /* Check the semaphores that were modified. */
@@ -772,8 +782,15 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop
                if (sops[i].sem_op > 0 ||
                        (sops[i].sem_op < 0 &&
                                sma->sem_base[sops[i].sem_num].semval == 0))
-                       if (update_queue(sma, sops[i].sem_num, pt))
+                       if (update_queue(sma, sops[i].sem_num, pt)) {
                                otime = 1;
+                               progress = 1;
+                       }
+       }
+done_checkretry:
+       if (progress) {
+               progress = 0;
+               goto retry_global;
        }
 done:
        if (otime)