--- e5cfa6ac44a0f1b72b5e44082737607a40abba0e +++ 5592e164a190d75ffa7d040314518037eaa45481 @@ -226,11 +226,6 @@ void cpu_idle(void) idle_notifier_call_chain(IDLE_START); tick_nohz_stop_sched_tick(1); while (!need_resched()) { -#ifdef CONFIG_HOTPLUG_CPU - if (cpu_is_offline(smp_processor_id())) - cpu_die(); -#endif - local_irq_disable(); #ifdef CONFIG_PL310_ERRATA_769419 wmb(); @@ -256,6 +251,10 @@ void cpu_idle(void) preempt_enable_no_resched(); schedule(); preempt_disable(); +#ifdef CONFIG_HOTPLUG_CPU + if (cpu_is_offline(smp_processor_id())) + cpu_die(); +#endif } } @@ -272,6 +271,15 @@ __setup("reboot=", reboot_setup); void machine_shutdown(void) { #ifdef CONFIG_SMP + /* + * Disable preemption so we're guaranteed to + * run to power off or reboot and prevent + * the possibility of switching to another + * thread that might wind up blocking on + * one of the stopped CPUs. + */ + preempt_disable(); + smp_send_stop(); #endif }