• Peter Zijlstra's avatar
    sched/fair: Plug hole between hotplug and active_load_balance() · edd8e41d
    Peter Zijlstra authored
    The load balancer applies cpu_active_mask to whatever sched_domains it
    finds, however in the case of active_balance there is a hole between
    setting rq->{active_balance,push_cpu} and running the stop_machine
    work doing the actual migration.
    
    The @push_cpu can go offline in this window, which would result in us
    moving a task onto a dead cpu, which is a fairly bad thing.
    
    Double check the active mask before the stop work does the migration.
    
      CPU0					CPU1
    
      <SoftIRQ>
    					stop_machine(takedown_cpu)
        load_balance()			cpu_stopper_thread()
          ...				  work = multi_cpu_stop
          stop_one_cpu_nowait(		    /* wait for CPU0 */
    	.func = active_load_balance_cpu_stop
          );
      </SoftIRQ>
    
      cpu_stopper_thread()
        work = multi_cpu_stop
          /* sync with CPU1 */
    					    take_cpu_down()
    					<idle>
    					  play_dead();
    
        work = active_load_balance_cpu_stop
          set_task_cpu(p, CPU1); /* oops!! */
    Reported-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Link: http://lkml.kernel.org/r/20170907150614.044460912@infradead.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    edd8e41d
fair.c 250 KB