|
@@ -285,6 +285,19 @@ notrace static void __cpuinit start_secondary(void *unused)
|
|
|
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
|
|
|
x86_platform.nmi_init();
|
|
|
|
|
|
+ /*
|
|
|
+ * Wait until the cpu which brought this one up marked it
|
|
|
+ * online before enabling interrupts. If we don't do that then
|
|
|
+ * we can end up waking up the softirq thread before this cpu
|
|
|
+ * reached the active state, which makes the scheduler unhappy
|
|
|
+ * and schedule the softirq thread on the wrong cpu. This is
|
|
|
+ * only observable with forced threaded interrupts, but in
|
|
|
+ * theory it could also happen w/o them. It's just way harder
|
|
|
+ * to achieve.
|
|
|
+ */
|
|
|
+ while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask))
|
|
|
+ cpu_relax();
|
|
|
+
|
|
|
/* enable local interrupts */
|
|
|
local_irq_enable();
|
|
|
|