From d914d4d4974529da898f2d2618e39df757147c2f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 17 Jun 2019 23:35:19 +0300 Subject: arm64: Implement panic_smp_self_stop() 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. Acked-by: Will Deacon Signed-off-by: Aaro Koskinen Signed-off-by: Catalin Marinas --- arch/arm64/kernel/smp.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'arch/arm64/kernel') diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 932461da5dd7..434d6714358b 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -841,18 +841,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 @@ -903,7 +910,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; -- cgit v1.2.3