summaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2006-03-25 03:07:48 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-25 08:22:57 -0800
commit05eeae208d08a05a6980cf2ff61f02843c0955fd (patch)
treebe6c6c4e16cfac07edf437a1f74ef027ada8ccc7 /mm
parentc1f5a1944657ba6abe375e3bb2a3238a46849f70 (diff)
downloadlinux-stable-05eeae208d08a05a6980cf2ff61f02843c0955fd.tar.gz
linux-stable-05eeae208d08a05a6980cf2ff61f02843c0955fd.tar.bz2
linux-stable-05eeae208d08a05a6980cf2ff61f02843c0955fd.zip
[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 'mm')
-rw-r--r--mm/vmscan.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index fd572bbdc9f5..78865c849f8f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1356,7 +1356,9 @@ static int __init kswapd_init(void)
pid = kernel_thread(kswapd, pgdat, CLONE_KERNEL);
BUG_ON(pid < 0);
+ read_lock(&tasklist_lock);
pgdat->kswapd = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock);
}
total_memory = nr_free_pagecache_pages();
hotcpu_notifier(cpu_callback, 0);