summaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2014-12-08 18:58:19 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2014-12-09 00:36:11 -0500
commit7c5c92ed56d932b2c19c3f8aea86369509407d33 (patch)
tree242767f52471da20317cd85b4f6a6057f02e1aac /arch/powerpc
parent56548fc0e86cb9156af7a7e1f15ba78f251dafaf (diff)
powerpc: Secondary CPUs must set cpu_callin_map after setting active and online
I have a busy ppc64le KVM box where guests sometimes hit the infamous "kernel BUG at kernel/smpboot.c:134!" issue during boot: BUG_ON(td->cpu != smp_processor_id()); Basically a per CPU hotplug thread scheduled on the wrong CPU. The oops output confirms it: CPU: 0 Comm: watchdog/130 The problem is that we aren't ensuring the CPU active and online bits are set before allowing the master to continue on. The master unparks the secondary CPUs kthreads and the scheduler looks for a CPU to run on. It calls select_task_rq and realises the suggested CPU is not in the cpus_allowed mask. It then ends up in select_fallback_rq, and since the active and online bits aren't set we choose some other CPU to run on. Cc: stable@vger.kernel.org Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/smp.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 8b2d2dc8ef10..8ec017cb4446 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -700,7 +700,6 @@ void start_secondary(void *unused)
700 smp_store_cpu_info(cpu); 700 smp_store_cpu_info(cpu);
701 set_dec(tb_ticks_per_jiffy); 701 set_dec(tb_ticks_per_jiffy);
702 preempt_disable(); 702 preempt_disable();
703 cpu_callin_map[cpu] = 1;
704 703
705 if (smp_ops->setup_cpu) 704 if (smp_ops->setup_cpu)
706 smp_ops->setup_cpu(cpu); 705 smp_ops->setup_cpu(cpu);
@@ -739,6 +738,14 @@ void start_secondary(void *unused)
739 notify_cpu_starting(cpu); 738 notify_cpu_starting(cpu);
740 set_cpu_online(cpu, true); 739 set_cpu_online(cpu, true);
741 740
741 /*
742 * CPU must be marked active and online before we signal back to the
743 * master, because the scheduler needs to see the cpu_online and
744 * cpu_active bits set.
745 */
746 smp_wmb();
747 cpu_callin_map[cpu] = 1;
748
742 local_irq_enable(); 749 local_irq_enable();
743 750
744 cpu_startup_entry(CPUHP_ONLINE); 751 cpu_startup_entry(CPUHP_ONLINE);