aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorManfred Spraul <manfred@colorfullife.com>2008-07-25 04:48:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-25 13:53:42 -0400
commit380af1b33b3ff92df5cda96329b58f5d1b6b5a53 (patch)
tree9a47d66c18e4aae2093a708a7509c0f188ee0bd1 /include
parenta1193f8ec091cd8fd309cc2982abe4499f6f2b4d (diff)
ipc/sem.c: rewrite undo list locking
The attached patch: - reverses the locking order of ulp->lock and sem_lock: Previously, it was first ulp->lock, then inside sem_lock. Now it's the other way around. - converts the undo structure to rcu. Benefits: - With the old locking order, IPC_RMID could not kfree the undo structures. The stale entries remained in the linked lists and were released later. - The patch fixes a a race in semtimedop(): if both IPC_RMID and a semget() that recreates exactly the same id happen between find_alloc_undo() and sem_lock, then semtimedop() would access already kfree'd memory. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Manfred Spraul <manfred@colorfullife.com> Reviewed-by: Nadia Derbey <Nadia.Derbey@bull.net> Cc: Pierre Peiffer <peifferp@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/sem.h6
1 files changed, 5 insertions, 1 deletions
diff --git a/include/linux/sem.h b/include/linux/sem.h
index d42599395d79..1b191c176bcd 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -78,6 +78,7 @@ struct seminfo {
78 78
79#ifdef __KERNEL__ 79#ifdef __KERNEL__
80#include <asm/atomic.h> 80#include <asm/atomic.h>
81#include <linux/rcupdate.h>
81 82
82struct task_struct; 83struct task_struct;
83 84
@@ -114,7 +115,10 @@ struct sem_queue {
114 * when the process exits. 115 * when the process exits.
115 */ 116 */
116struct sem_undo { 117struct sem_undo {
117 struct list_head list_proc; /* per-process list: all undos from one process */ 118 struct list_head list_proc; /* per-process list: all undos from one process. */
119 /* rcu protected */
120 struct rcu_head rcu; /* rcu struct for sem_undo() */
121 struct sem_undo_list *ulp; /* sem_undo_list for the process */
118 struct list_head list_id; /* per semaphore array list: all undos for one array */ 122 struct list_head list_id; /* per semaphore array list: all undos for one array */
119 int semid; /* semaphore set identifier */ 123 int semid; /* semaphore set identifier */
120 short * semadj; /* array of adjustments, one per semaphore */ 124 short * semadj; /* array of adjustments, one per semaphore */