• Anton Blanchard's avatar
    [PATCH] fix scheduler deadlock · e9028b0f
    Anton Blanchard authored
    We have noticed lockups during boot when stress testing kexec on ppc64.
    Two cpus would deadlock in scheduler code trying to grab already taken
    spinlocks.
    
    The double_rq_lock code uses the address of the runqueue to order the
    taking of multiple locks.  This address is a per cpu variable:
    
    	if (rq1 < rq2) {
    		spin_lock(&rq1->lock);
    		spin_lock(&rq2->lock);
    	} else {
    		spin_lock(&rq2->lock);
    		spin_lock(&rq1->lock);
    	}
    
    On the other hand, the code in wake_sleeping_dependent uses the cpu id
    order to grab locks:
    
    	for_each_cpu_mask(i, sibling_map)
    		spin_lock(&cpu_rq(i)->lock);
    
    This means we rely on the address of per cpu data increasing as cpu ids
    increase.  While this will be true for the generic percpu implementation it
    may not be true for arch specific implementations.
    
    One way to solve this is to always take runqueues in cpu id order. To do
    this we add a cpu variable to the runqueue and check it in the
    double runqueue locking functions.
    Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
    Acked-by: default avatarIngo Molnar <mingo@elte.hu>
    Cc: <stable@kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    e9028b0f
sched.c 153 KB