summaryrefslogtreecommitdiff
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorAndrew Morton <akpm@digeo.com>2003-06-20 08:13:53 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-06-20 08:13:53 -0700
commit1327ca85e19e5ea19c9fcab0b54f093ddaaca31a (patch)
treeeb468430b12517233fb32fac4e4ef9032f810a22 /kernel/fork.c
parent0d5ff9d0ca5801ccc5dd8f1f6023629bbc6090da (diff)
[PATCH] sysv semundo fixes
From: Manfred Spraul <manfred@colorfullife.com> The CLONE_SYSVSEM implementation is racy: it does an (atomic_read(->refcnt) ==1) instead of atomic_dec_and_test calls in the exit handling. The patch fixes that. Additionally, the patch contains the following changes: - lock_undo() locks the list of undo structures. The lock is held throughout the semop() syscall, but that's unnecessary - we can drop it immediately after the lookup. - undo structures are only allocated when necessary. The need for undo structures is only noticed in the middle of the semop operation, while holding the semaphore array spinlock. The result is a convoluted unlock&revalidate implementation. I've reordered the code, and now the undo allocation can happen before acquiring the semaphore array spinlock. As a bonus, less code runs under the semaphore array spinlock. - sysvsem.sleep_list looks like code to handle oopses: if an oops kills a thread that sleeps in sys_timedsemop(), then sem_exit tries to recover. I've removed that - too fragile.
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 0fe154adc3ef..5ef2dca02354 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -39,7 +39,7 @@
#include <asm/tlbflush.h>
extern int copy_semundo(unsigned long clone_flags, struct task_struct *tsk);
-extern void exit_semundo(struct task_struct *tsk);
+extern void exit_sem(struct task_struct *tsk);
/* The idle threads do not count..
* Protected by write_lock_irq(&tasklist_lock)
@@ -1032,7 +1032,7 @@ bad_fork_cleanup_fs:
bad_fork_cleanup_files:
exit_files(p); /* blocking */
bad_fork_cleanup_semundo:
- exit_semundo(p);
+ exit_sem(p);
bad_fork_cleanup_security:
security_task_free(p);
bad_fork_cleanup: