From: Rusty Russell We can't just return from kthread when something goes wrong: use goto. Also, we wake then immediately kthread_stop() the thread: it's possible that it may not have run the function at all yet. Use a completion. --- kernel/module.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diff -puN kernel/module.c~module-removal-use-kthread-fixes kernel/module.c --- 25/kernel/module.c~module-removal-use-kthread-fixes 2004-02-03 21:06:15.000000000 -0800 +++ 25-akpm/kernel/module.c 2004-02-03 21:06:15.000000000 -0800 @@ -568,6 +568,7 @@ struct stopref struct module *mod; int flags; int *forced; + struct completion started; }; static int spawn_stopref(void *data) @@ -577,6 +578,8 @@ static int spawn_stopref(void *data) unsigned int i, cpu = smp_processor_id(); int ret = 0; + complete(&sref->started); + /* One high-prio thread per cpu. We'll do one (any one). */ set_cpus_allowed(current, cpumask_of_cpu(cpu)); sys_sched_setscheduler(current->pid, SCHED_FIFO, ¶m); @@ -601,7 +604,7 @@ static int spawn_stopref(void *data) /* If some failed, kill them all. */ if (ret < 0) { stopref_set_state(STOPREF_EXIT, 1); - return ret; + goto out; } /* Don't schedule us away at this point, please. */ @@ -619,6 +622,7 @@ static int spawn_stopref(void *data) stopref_set_state(STOPREF_EXIT, 0); preempt_enable(); +out: /* Wait for kthread_stop */ while (!signal_pending(current)) { __set_current_state(TASK_INTERRUPTIBLE); @@ -633,13 +637,17 @@ static int try_stop_module(struct module struct stopref sref = { mod, flags, forced }; int ret; + init_completion(&sref.started); + /* No CPUs can come up or down during this. */ lock_cpu_hotplug(); p = kthread_run(spawn_stopref, &sref, "krmmod"); if (IS_ERR(p)) ret = PTR_ERR(p); - else + else { + wait_for_completion(&sref.started); ret = kthread_stop(p); + } unlock_cpu_hotplug(); return ret; } _