Skip to content
  • Peter Zijlstra's avatar
    kthread, sched/core: Fix kthread_parkme() (again...) · 1cef1150
    Peter Zijlstra authored
    Gaurav reports that commit:
    
      85f1abe0
    
     ("kthread, sched/wait: Fix kthread_parkme() completion issue")
    
    isn't working for him. Because of the following race:
    
    > controller Thread                               CPUHP Thread
    > takedown_cpu
    > kthread_park
    > kthread_parkme
    > Set KTHREAD_SHOULD_PARK
    >                                                 smpboot_thread_fn
    >                                                 set Task interruptible
    >
    >
    > wake_up_process
    >  if (!(p->state & state))
    >                 goto out;
    >
    >                                                 Kthread_parkme
    >                                                 SET TASK_PARKED
    >                                                 schedule
    >                                                 raw_spin_lock(&rq->lock)
    > ttwu_remote
    > waiting for __task_rq_lock
    >                                                 context_switch
    >
    >                                                 finish_lock_switch
    >
    >
    >
    >                                                 Case TASK_PARKED
    >                                                 kthread_park_complete
    >
    >
    > SET Running
    
    Furthermore, Oleg noticed that the whole scheduler TASK_PARKED
    handling is buggered because the TASK_DEAD thing is done with
    preemption disabled, the current code can still complete early on
    preemption :/
    
    So basically revert that earlier fix and go with a variant of the
    alternative mentioned in the commit. Promote TASK_PARKED to special
    state to avoid the store-store issue on task->state leading to the
    WARN in kthread_unpark() -> __kthread_bind().
    
    But in addition, add wait_task_inactive() to kthread_park() to ensure
    the task really is PARKED when we return from kthread_park(). This
    avoids the whole kthread still gets migrated nonsense -- although it
    would be really good to get this done differently.
    
    Reported-by: default avatarGaurav Kohli <gkohli@codeaurora.org>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Fixes: 85f1abe0
    
     ("kthread, sched/wait: Fix kthread_parkme() completion issue")
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    1cef1150