]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Oct 2013 00:10:41 +0000 (17:10 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Oct 2013 00:10:41 +0000 (17:10 -0700)
added patches:
ipc-sem.c-optimize-sem_lock.patch
ipc-sem.c-synchronize-the-proc-interface.patch
ipc-sem.c-update-sem_otime-for-all-operations.patch

queue-3.11/ipc-sem.c-optimize-sem_lock.patch [new file with mode: 0644]
queue-3.11/ipc-sem.c-synchronize-the-proc-interface.patch [new file with mode: 0644]
queue-3.11/ipc-sem.c-update-sem_otime-for-all-operations.patch [new file with mode: 0644]
queue-3.11/series

diff --git a/queue-3.11/ipc-sem.c-optimize-sem_lock.patch b/queue-3.11/ipc-sem.c-optimize-sem_lock.patch
new file mode 100644 (file)
index 0000000..91422f8
--- /dev/null
@@ -0,0 +1,55 @@
+From 6d07b68ce16ae9535955ba2059dedba5309c3ca1 Mon Sep 17 00:00:00 2001
+From: Manfred Spraul <manfred@colorfullife.com>
+Date: Mon, 30 Sep 2013 13:45:06 -0700
+Subject: ipc/sem.c: optimize sem_lock()
+
+From: Manfred Spraul <manfred@colorfullife.com>
+
+commit 6d07b68ce16ae9535955ba2059dedba5309c3ca1 upstream.
+
+Operations that need access to the whole array must guarantee that there
+are no simple operations ongoing.  Right now this is achieved by
+spin_unlock_wait(sem->lock) on all semaphores.
+
+If complex_count is nonzero, then this spin_unlock_wait() is not
+necessary, because it was already performed in the past by the thread
+that increased complex_count and even though sem_perm.lock was dropped
+inbetween, no simple operation could have started, because simple
+operations cannot start when complex_count is non-zero.
+
+Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
+Cc: Mike Galbraith <bitbucket@online.de>
+Cc: Rik van Riel <riel@redhat.com>
+Reviewed-by: Davidlohr Bueso <davidlohr@hp.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/sem.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -248,12 +248,20 @@ static void merge_queues(struct sem_arra
+  * Caller must own sem_perm.lock.
+  * New simple ops cannot start, because simple ops first check
+  * that sem_perm.lock is free.
++ * that a) sem_perm.lock is free and b) complex_count is 0.
+  */
+ static void sem_wait_array(struct sem_array *sma)
+ {
+       int i;
+       struct sem *sem;
++      if (sma->complex_count)  {
++              /* The thread that increased sma->complex_count waited on
++               * all sem->lock locks. Thus we don't need to wait again.
++               */
++              return;
++      }
++
+       for (i = 0; i < sma->sem_nsems; i++) {
+               sem = sma->sem_base + i;
+               spin_unlock_wait(&sem->lock);
diff --git a/queue-3.11/ipc-sem.c-synchronize-the-proc-interface.patch b/queue-3.11/ipc-sem.c-synchronize-the-proc-interface.patch
new file mode 100644 (file)
index 0000000..1ca7d80
--- /dev/null
@@ -0,0 +1,46 @@
+From d8c633766ad88527f25d9f81a5c2f083d78a2b39 Mon Sep 17 00:00:00 2001
+From: Manfred Spraul <manfred@colorfullife.com>
+Date: Mon, 30 Sep 2013 13:45:07 -0700
+Subject: ipc/sem.c: synchronize the proc interface
+
+From: Manfred Spraul <manfred@colorfullife.com>
+
+commit d8c633766ad88527f25d9f81a5c2f083d78a2b39 upstream.
+
+The proc interface is not aware of sem_lock(), it instead calls
+ipc_lock_object() directly.  This means that simple semop() operations
+can run in parallel with the proc interface.  Right now, this is
+uncritical, because the implementation doesn't do anything that requires
+a proper synchronization.
+
+But it is dangerous and therefore should be fixed.
+
+Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
+Cc: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/sem.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -2103,6 +2103,14 @@ static int sysvipc_sem_proc_show(struct
+       struct sem_array *sma = it;
+       time_t sem_otime;
++      /*
++       * The proc interface isn't aware of sem_lock(), it calls
++       * ipc_lock_object() directly (in sysvipc_find_ipc).
++       * In order to stay compatible with sem_lock(), we must wait until
++       * all simple semop() calls have left their critical regions.
++       */
++      sem_wait_array(sma);
++
+       sem_otime = get_semotime(sma);
+       return seq_printf(s,
diff --git a/queue-3.11/ipc-sem.c-update-sem_otime-for-all-operations.patch b/queue-3.11/ipc-sem.c-update-sem_otime-for-all-operations.patch
new file mode 100644 (file)
index 0000000..d004617
--- /dev/null
@@ -0,0 +1,103 @@
+From 0e8c665699e953fa58dc1b0b0d09e5dce7343cc7 Mon Sep 17 00:00:00 2001
+From: Manfred Spraul <manfred@colorfullife.com>
+Date: Mon, 30 Sep 2013 13:45:25 -0700
+Subject: ipc/sem.c: update sem_otime for all operations
+
+From: Manfred Spraul <manfred@colorfullife.com>
+
+commit 0e8c665699e953fa58dc1b0b0d09e5dce7343cc7 upstream.
+
+In commit 0a2b9d4c7967 ("ipc/sem.c: move wake_up_process out of the
+spinlock section"), the update of semaphore's sem_otime(last semop time)
+was moved to one central position (do_smart_update).
+
+But since do_smart_update() is only called for operations that modify
+the array, this means that wait-for-zero semops do not update sem_otime
+anymore.
+
+The fix is simple:
+Non-alter operations must update sem_otime.
+
+[akpm@linux-foundation.org: coding-style fixes]
+Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
+Reported-by: Jia He <jiakernel@gmail.com>
+Tested-by: Jia He <jiakernel@gmail.com>
+Cc: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/sem.c |   42 +++++++++++++++++++++++++++++-------------
+ 1 file changed, 29 insertions(+), 13 deletions(-)
+
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -918,6 +918,24 @@ again:
+ }
+ /**
++ * set_semotime(sma, sops) - set sem_otime
++ * @sma: semaphore array
++ * @sops: operations that modified the array, may be NULL
++ *
++ * sem_otime is replicated to avoid cache line trashing.
++ * This function sets one instance to the current time.
++ */
++static void set_semotime(struct sem_array *sma, struct sembuf *sops)
++{
++      if (sops == NULL) {
++              sma->sem_base[0].sem_otime = get_seconds();
++      } else {
++              sma->sem_base[sops[0].sem_num].sem_otime =
++                                                      get_seconds();
++      }
++}
++
++/**
+  * do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue
+  * @sma: semaphore array
+  * @sops: operations that were performed
+@@ -967,17 +985,10 @@ static void do_smart_update(struct sem_a
+                       }
+               }
+       }
+-      if (otime) {
+-              if (sops == NULL) {
+-                      sma->sem_base[0].sem_otime = get_seconds();
+-              } else {
+-                      sma->sem_base[sops[0].sem_num].sem_otime =
+-                                                              get_seconds();
+-              }
+-      }
++      if (otime)
++              set_semotime(sma, sops);
+ }
+-
+ /* The following counts are associated to each semaphore:
+  *   semncnt        number of tasks waiting on semval being nonzero
+  *   semzcnt        number of tasks waiting on semval being zero
+@@ -1839,12 +1850,17 @@ SYSCALL_DEFINE4(semtimedop, int, semid,
+       error = perform_atomic_semop(sma, sops, nsops, un,
+                                       task_tgid_vnr(current));
+-      if (error <= 0) {
+-              if (alter && error == 0)
++      if (error == 0) {
++              /* If the operation was successful, then do
++               * the required updates.
++               */
++              if (alter)
+                       do_smart_update(sma, sops, nsops, 1, &tasks);
+-
+-              goto out_unlock_free;
++              else
++                      set_semotime(sma, sops);
+       }
++      if (error <= 0)
++              goto out_unlock_free;
+       /* We need to sleep on this operation, so we put the current
+        * task into the pending queue and go to sleep.
index df3ee059fb0fe80e2d249e51eb3061a7c0b60de9..76434158bb546980270cd7a82cd510da088cb1f6 100644 (file)
@@ -44,3 +44,6 @@ ipc-shm-guard-against-non-existant-vma-in-shmdt-2.patch
 ipc-drop-ipc_lock_by_ptr.patch
 ipc-shm-drop-shm_lock_check.patch
 ipc-drop-ipc_lock_check.patch
+ipc-sem.c-optimize-sem_lock.patch
+ipc-sem.c-synchronize-the-proc-interface.patch
+ipc-sem.c-update-sem_otime-for-all-operations.patch