Message ID | 20190617203519.328-2-aaro.koskinen@iki.fi (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2,1/2] arm64: Improve parking of stopped CPUs | expand |
On Mon, Jun 17, 2019 at 11:35:19PM +0300, Aaro Koskinen wrote: > From: Aaro Koskinen <aaro.koskinen@nokia.com> > > Currently arm64 uses the default implementation of panic_smp_self_stop() > where the CPU runs in a cpu_relax() loop unable to receive IPIs anymore. > As a result, when two CPUs panic() simultaneously we get "SMP: failed to > stop secondary CPUs" warnings and extra delays before a reset, because > smp_send_stop() still tries to stop the other paniced CPU. > > Provide an implementation of panic_smp_self_stop() that is identical to > the IPI CPU stop handler, so that the online status of stopped CPUs gets > properly updated. > > Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com> > --- > > v2: Update the commit log > Rename ipi_cpu_stop() to local_cpu_stop() and make it void func > Add a comment for panic_smp_self_stop() > > v1: https://patchwork.kernel.org/patch/10988103/ > > arch/arm64/kernel/smp.c | 19 +++++++++++++------ > 1 file changed, 13 insertions(+), 6 deletions(-) Acked-by: Will Deacon <will.deacon@arm.com> Will
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 1a1b96a50245..1ac4aa34ffb6 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -845,18 +845,25 @@ void arch_irq_work_raise(void) } #endif -/* - * ipi_cpu_stop - handle IPI from smp_send_stop() - */ -static void ipi_cpu_stop(unsigned int cpu) +static void local_cpu_stop(void) { - set_cpu_online(cpu, false); + set_cpu_online(smp_processor_id(), false); local_daif_mask(); sdei_mask_local_cpu(); cpu_park_loop(); } +/* + * We need to implement panic_smp_self_stop() for parallel panic() calls, so + * that cpu_online_mask gets correctly updated and smp_send_stop() can skip + * CPUs that have already stopped themselves. + */ +void panic_smp_self_stop(void) +{ + local_cpu_stop(); +} + #ifdef CONFIG_KEXEC_CORE static atomic_t waiting_for_crash_ipi = ATOMIC_INIT(0); #endif @@ -907,7 +914,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs) case IPI_CPU_STOP: irq_enter(); - ipi_cpu_stop(cpu); + local_cpu_stop(); irq_exit(); break;