[PATCH] powerpc/crash: save cpu register data in crash_smp_send_stop()
Hari Bathini
hbathini at linux.ibm.com
Sat May 7 02:39:33 AEST 2022
Capture register data for secondary CPUs in crash_smp_send_stop()
instead of doing it much later in crash_kexec_prepare_cpus() function
with another set of NMI IPIs to secondary CPUs. This change avoids
unnecessarily tricky post processing of data to get the right
backtrace for these CPUs.
Signed-off-by: Hari Bathini <hbathini at linux.ibm.com>
---
arch/powerpc/kernel/smp.c | 40 --------------------------
arch/powerpc/kexec/crash.c | 58 ++++++++++++++++++++++++++------------
2 files changed, 40 insertions(+), 58 deletions(-)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index de0f6f09a5dd..7621c3d84c1c 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -60,7 +60,6 @@
#include <asm/cpu_has_feature.h>
#include <asm/ftrace.h>
#include <asm/kup.h>
-#include <asm/fadump.h>
#ifdef DEBUG
#include <asm/udbg.h>
@@ -620,45 +619,6 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
}
#endif
-#ifdef CONFIG_NMI_IPI
-static void crash_stop_this_cpu(struct pt_regs *regs)
-#else
-static void crash_stop_this_cpu(void *dummy)
-#endif
-{
- /*
- * Just busy wait here and avoid marking CPU as offline to ensure
- * register data is captured appropriately.
- */
- while (1)
- cpu_relax();
-}
-
-void crash_smp_send_stop(void)
-{
- static bool stopped = false;
-
- /*
- * In case of fadump, register data for all CPUs is captured by f/w
- * on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before
- * this rtas call to avoid tricky post processing of those CPUs'
- * backtraces.
- */
- if (should_fadump_crash())
- return;
-
- if (stopped)
- return;
-
- stopped = true;
-
-#ifdef CONFIG_NMI_IPI
- smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 1000000);
-#else
- smp_call_function(crash_stop_this_cpu, NULL, 0);
-#endif /* CONFIG_NMI_IPI */
-}
-
#ifdef CONFIG_NMI_IPI
static void nmi_stop_this_cpu(struct pt_regs *regs)
{
diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
index 22ceeeb705ab..f06dfe71caca 100644
--- a/arch/powerpc/kexec/crash.c
+++ b/arch/powerpc/kexec/crash.c
@@ -25,6 +25,7 @@
#include <asm/setjmp.h>
#include <asm/debug.h>
#include <asm/interrupt.h>
+#include <asm/fadump.h>
/*
* The primary CPU waits a while for all secondary CPUs to enter. This is to
@@ -102,7 +103,7 @@ void crash_ipi_callback(struct pt_regs *regs)
/* NOTREACHED */
}
-static void crash_kexec_prepare_cpus(int cpu)
+static void crash_kexec_prepare_cpus(void)
{
unsigned int msecs;
volatile unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
@@ -203,7 +204,7 @@ void crash_kexec_secondary(struct pt_regs *regs)
#else /* ! CONFIG_SMP */
-static void crash_kexec_prepare_cpus(int cpu)
+static void crash_kexec_prepare_cpus(void)
{
/*
* move the secondaries to us so that we can copy
@@ -249,6 +250,42 @@ static void __maybe_unused crash_kexec_wait_realmode(int cpu)
static inline void crash_kexec_wait_realmode(int cpu) {}
#endif /* CONFIG_SMP && CONFIG_PPC64 */
+void crash_smp_send_stop(void)
+{
+ static int cpus_stopped;
+
+ /*
+ * In case of fadump, register data for all CPUs is captured by f/w
+ * on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before
+ * this rtas call to avoid tricky post processing of those CPUs'
+ * backtraces.
+ */
+ if (should_fadump_crash())
+ return;
+
+ if (cpus_stopped)
+ return;
+
+ cpus_stopped = 1;
+
+ /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
+ printk_deferred_enter();
+
+ /*
+ * This function is only called after the system
+ * has panicked or is otherwise in a critical state.
+ * The minimum amount of code to allow a kexec'd kernel
+ * to run successfully needs to happen here.
+ *
+ * In practice this means stopping other cpus in
+ * an SMP system.
+ * The kernel is broken so disable interrupts.
+ */
+ hard_irq_disable();
+
+ crash_kexec_prepare_cpus();
+}
+
/*
* Register a function to be called on shutdown. Only use this if you
* can't reset your device in the second kernel.
@@ -312,21 +349,6 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
unsigned int i;
int (*old_handler)(struct pt_regs *regs);
- /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
- printk_deferred_enter();
-
- /*
- * This function is only called after the system
- * has panicked or is otherwise in a critical state.
- * The minimum amount of code to allow a kexec'd kernel
- * to run successfully needs to happen here.
- *
- * In practice this means stopping other cpus in
- * an SMP system.
- * The kernel is broken so disable interrupts.
- */
- hard_irq_disable();
-
/*
* Make a note of crashing cpu. Will be used in machine_kexec
* such that another IPI will not be sent.
@@ -340,7 +362,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
if (TRAP(regs) == INTERRUPT_SYSTEM_RESET)
mdelay(PRIMARY_TIMEOUT);
- crash_kexec_prepare_cpus(crashing_cpu);
+ crash_smp_send_stop();
crash_save_cpu(regs, crashing_cpu);
--
2.35.1
More information about the Linuxppc-dev
mailing list