From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-x241.google.com (mail-pf0-x241.google.com [IPv6:2607:f8b0:400e:c00::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3yL88j33PgzDqjm for ; Mon, 23 Oct 2017 19:05:25 +1100 (AEDT) Received: by mail-pf0-x241.google.com with SMTP id d28so16533324pfe.2 for ; Mon, 23 Oct 2017 01:05:25 -0700 (PDT) From: Nicholas Piggin To: linuxppc-dev@lists.ozlabs.org Cc: Nicholas Piggin Subject: [PATCH v2 2/3] powerpc: use NMI IPI for smp_send_stop Date: Mon, 23 Oct 2017 18:05:06 +1000 Message-Id: <20171023080507.21974-3-npiggin@gmail.com> In-Reply-To: <20171023080507.21974-1-npiggin@gmail.com> References: <20171023080507.21974-1-npiggin@gmail.com> List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Use the NMI IPI rather than smp_call_function for smp_send_stop. Have stopped CPUs hard disable interrupts rather than just soft disable. This function is used in crash/panic/shutdown paths to bring other CPUs down as quickly and reliably as possible, and minimizing their potential to cause trouble. Avoiding the Linux smp_call_function infrastructure and (if supported) using true NMI IPIs makes this more robust. Also use spin loop primitives in the stop callback, mainly to help processing speed of the active thread speed in the simulator. Signed-off-by: Nicholas Piggin --- arch/powerpc/kernel/smp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index e0a4c1f82e25..ce891030d925 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -547,19 +547,20 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) } #endif -static void stop_this_cpu(void *dummy) +static void __noreturn stop_this_cpu(struct pt_regs *regs) { /* Remove this CPU */ set_cpu_online(smp_processor_id(), false); - local_irq_disable(); + hard_irq_disable(); + spin_begin(); while (1) - ; + spin_cpu_relax(); } void smp_send_stop(void) { - smp_call_function(stop_this_cpu, NULL, 0); + smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, stop_this_cpu, 1000000); } struct thread_info *current_set[NR_CPUS]; -- 2.13.3