aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-04-16 18:26:41 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:26:41 -0400
commitd28446fe2d87ea344c14741c39962dcc7aee5c78 (patch)
treeb41bec77e5e5123f8f5349eb01ced9ee8fd9a924
parent187a27845a9dc1c3da3995e24625ccf2e7a346aa (diff)
[PATCH] md: close a small race in md thread deregistration
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 <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/md.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index aa72c88a024f..44a164965546 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2840,16 +2840,6 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
2840 return thread; 2840 return thread;
2841} 2841}
2842 2842
2843static void md_interrupt_thread(mdk_thread_t *thread)
2844{
2845 if (!thread->tsk) {
2846 MD_BUG();
2847 return;
2848 }
2849 dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
2850 send_sig(SIGKILL, thread->tsk, 1);
2851}
2852
2853void md_unregister_thread(mdk_thread_t *thread) 2843void md_unregister_thread(mdk_thread_t *thread)
2854{ 2844{
2855 struct completion event; 2845 struct completion event;
@@ -2857,9 +2847,15 @@ void md_unregister_thread(mdk_thread_t *thread)
2857 init_completion(&event); 2847 init_completion(&event);
2858 2848
2859 thread->event = &event; 2849 thread->event = &event;
2850
2851 /* As soon as ->run is set to NULL, the task could disappear,
2852 * so we need to hold tasklist_lock until we have sent the signal
2853 */
2854 dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
2855 read_lock(&tasklist_lock);
2860 thread->run = NULL; 2856 thread->run = NULL;
2861 thread->name = NULL; 2857 send_sig(SIGKILL, thread->tsk, 1);
2862 md_interrupt_thread(thread); 2858 read_unlock(&tasklist_lock);
2863 wait_for_completion(&event); 2859 wait_for_completion(&event);
2864 kfree(thread); 2860 kfree(thread);
2865} 2861}