Skip to content
  • Peter Zijlstra's avatar
    kthread, sched/wait: Fix kthread_parkme() wait-loop · 741a76b3
    Peter Zijlstra authored
    
    
    Gaurav reported a problem with __kthread_parkme() where a concurrent
    try_to_wake_up() could result in competing stores to ->state which,
    when the TASK_PARKED store got lost bad things would happen.
    
    The comment near set_current_state() actually mentions this competing
    store, but only mentions the case against TASK_RUNNING. This same
    store, with different timing, can happen against a subsequent !RUNNING
    store.
    
    This normally is not a problem, because as per that same comment, the
    !RUNNING state store is inside a condition based wait-loop:
    
      for (;;) {
        set_current_state(TASK_UNINTERRUPTIBLE);
        if (!need_sleep)
          break;
        schedule();
      }
      __set_current_state(TASK_RUNNING);
    
    If we loose the (first) TASK_UNINTERRUPTIBLE store to a previous
    (concurrent) wakeup, the schedule() will NO-OP and we'll go around the
    loop once more.
    
    The problem here is that the TASK_PARKED store is not inside the
    KTHREAD_SHOULD_PARK condition wait-loop.
    
    There is a genuine issue with sleeps that do not have a condition;
    this is addressed in a subsequent patch.
    
    Reported-by: default avatarGaurav Kohli <gkohli@codeaurora.org>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: default avatarOleg Nesterov <oleg@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    741a76b3