kthread_stop() had to use to_live_kthread() simply because it was not
possible to access kthread->exited after the exiting kthread clears
task_struct->vfork_done. Now that to_kthread() is always valid we can
do wake_up_process() + wait_for_completion() unconditionally, we don't
care if it has already passed complete_vfork_done() or even dead.

The exiting kthread can get the spurious wakeup after mm_release() but
this is possible without this change too and this is fine, do_task_dead()
ensures that this can't make any harm.

Note: we can even change this function to use task_work_add() and avoid
->vfork_done altogether, probably we will do this later.

Signed-off-by: Oleg Nesterov <o...@redhat.com>
---
 kernel/kthread.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/kernel/kthread.c b/kernel/kthread.c
index 7891a94..4dcbc8b 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -532,13 +532,11 @@ int kthread_stop(struct task_struct *k)
        trace_sched_kthread_stop(k);
 
        get_task_struct(k);
-       kthread = to_live_kthread(k);
-       if (kthread) {
-               set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);
-               __kthread_unpark(k, kthread);
-               wake_up_process(k);
-               wait_for_completion(&kthread->exited);
-       }
+       kthread = to_kthread(k);
+       set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);
+       __kthread_unpark(k, kthread);
+       wake_up_process(k);
+       wait_for_completion(&kthread->exited);
        ret = k->exit_code;
        put_task_struct(k);
 
-- 
2.5.0


Reply via email to