• Peter Zijlstra's avatar
    sched: Fix TASK_WAKING vs fork deadlock · 0017d735
    Peter Zijlstra authored
    Oleg noticed a few races with the TASK_WAKING usage on fork.
    
     - since TASK_WAKING is basically a spinlock, it should be IRQ safe
     - since we set TASK_WAKING (*) without holding rq->lock it could
       be there still is a rq->lock holder, thereby not actually
       providing full serialization.
    
    (*) in fact we clear PF_STARTING, which in effect enables TASK_WAKING.
    
    Cure the second issue by not setting TASK_WAKING in sched_fork(), but
    only temporarily in wake_up_new_task() while calling select_task_rq().
    
    Cure the first by holding rq->lock around the select_task_rq() call,
    this will disable IRQs, this however requires that we push down the
    rq->lock release into select_task_rq_fair()'s cgroup stuff.
    
    Because select_task_rq_fair() still needs to drop the rq->lock we
    cannot fully get rid of TASK_WAKING.
    Reported-by: default avatarOleg Nesterov <oleg@redhat.com>
    Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
    LKML-Reference: <new-submission>
    Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
    0017d735
sched_fair.c 93.2 KB