diff options
author | Andrew Morton <akpm@osdl.org> | 2006-03-25 06:07:48 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-25 11:22:57 -0500 |
commit | 05eeae208d08a05a6980cf2ff61f02843c0955fd (patch) | |
tree | be6c6c4e16cfac07edf437a1f74ef027ada8ccc7 /kernel/kthread.c | |
parent | c1f5a1944657ba6abe375e3bb2a3238a46849f70 (diff) |
[PATCH] find_task_by_pid() needs tasklist_lock
A couple of places are forgetting to take it.
The kswapd case is probably unimportant. keventd_create_kthread() was racy.
The whole thing is a bit flakey: you start a kernel thread, get its pid from
kernel_thread() then look up its task_struct.
a) It assumes that pid recycling takes a "long" time.
b) We get a task_struct but no reference was taken on it. The owner of the
kswapd and kthread task_struct*'s must assume that the new thread won't
exit unexpectedly. Because if it does, they're left holding dead memory
and any attempt to control or stop that task will crash.
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/kthread.c')
-rw-r--r-- | kernel/kthread.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/kernel/kthread.c b/kernel/kthread.c index 6a5373868a98..c5f3c6613b6d 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
@@ -115,7 +115,9 @@ static void keventd_create_kthread(void *_create) | |||
115 | create->result = ERR_PTR(pid); | 115 | create->result = ERR_PTR(pid); |
116 | } else { | 116 | } else { |
117 | wait_for_completion(&create->started); | 117 | wait_for_completion(&create->started); |
118 | read_lock(&tasklist_lock); | ||
118 | create->result = find_task_by_pid(pid); | 119 | create->result = find_task_by_pid(pid); |
120 | read_unlock(&tasklist_lock); | ||
119 | } | 121 | } |
120 | complete(&create->done); | 122 | complete(&create->done); |
121 | } | 123 | } |