[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>
This commit is contained in:
parent
c1f5a19446
commit
05eeae208d
|
@ -115,7 +115,9 @@ static void keventd_create_kthread(void *_create)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue