From: NeilBrown There is a tiny race when de-registering an MD thread, in that the thread could disappear before it is set a SIGKILL, causing send_sig to have problems. This is most easily closed by holding tasklist_lock between enabling the thread to exit (setting ->run to NULL) and telling it to exit. (akpm: ick. Needs to use kthread API and stop using signals) Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- 25-akpm/drivers/md/md.c | 20 ++++++++------------ 1 files changed, 8 insertions(+), 12 deletions(-) diff -puN drivers/md/md.c~md-close-a-small-race-in-md-thread-deregistration drivers/md/md.c --- 25/drivers/md/md.c~md-close-a-small-race-in-md-thread-deregistration 2005-04-07 19:12:57.000000000 -0700 +++ 25-akpm/drivers/md/md.c 2005-04-07 19:14:24.000000000 -0700 @@ -2840,16 +2840,6 @@ mdk_thread_t *md_register_thread(void (* return thread; } -static void md_interrupt_thread(mdk_thread_t *thread) -{ - if (!thread->tsk) { - MD_BUG(); - return; - } - dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid); - send_sig(SIGKILL, thread->tsk, 1); -} - void md_unregister_thread(mdk_thread_t *thread) { struct completion event; @@ -2857,9 +2847,15 @@ void md_unregister_thread(mdk_thread_t * init_completion(&event); thread->event = &event; + + /* As soon as ->run is set to NULL, the task could disappear, + * so we need to hold tasklist_lock until we have sent the signal + */ + dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid); + read_lock(&tasklist_lock); thread->run = NULL; - thread->name = NULL; - md_interrupt_thread(thread); + send_sig(SIGKILL, thread->tsk, 1); + read_unlock(&tasklist_lock); wait_for_completion(&event); kfree(thread); } _