From: Andrew Morton 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 Signed-off-by: Andrew Morton --- kernel/kthread.c | 2 ++ mm/vmscan.c | 2 ++ 2 files changed, 4 insertions(+) diff -puN kernel/kthread.c~find_task_by_pid-needs-tasklist_lock kernel/kthread.c --- 25/kernel/kthread.c~find_task_by_pid-needs-tasklist_lock Fri Mar 10 14:20:57 2006 +++ 25-akpm/kernel/kthread.c Fri Mar 10 14:20:57 2006 @@ -115,7 +115,9 @@ static void keventd_create_kthread(void create->result = ERR_PTR(pid); } else { wait_for_completion(&create->started); + read_lock(&tasklist_lock); create->result = find_task_by_pid(pid); + read_unlock(&tasklist_lock); } complete(&create->done); } diff -puN mm/vmscan.c~find_task_by_pid-needs-tasklist_lock mm/vmscan.c --- 25/mm/vmscan.c~find_task_by_pid-needs-tasklist_lock Fri Mar 10 14:20:57 2006 +++ 25-akpm/mm/vmscan.c Fri Mar 10 14:21:40 2006 @@ -1849,7 +1849,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); _