[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251027133431.15321-3-cuiyunhui@bytedance.com>
Date: Mon, 27 Oct 2025 21:34:30 +0800
From: Yunhui Cui <cuiyunhui@...edance.com>
To: paul.walmsley@...ive.com,
palmer@...belt.com,
aou@...s.berkeley.edu,
alex@...ti.fr,
conor@...nel.org,
cuiyunhui@...edance.com,
luxu.kernel@...edance.com,
atishp@...osinc.com,
cleger@...osinc.com,
ajones@...tanamicro.com,
apatel@...tanamicro.com,
linux-kernel@...r.kernel.org,
linux-riscv@...ts.infradead.org,
songshuaishuai@...ylab.org,
bjorn@...osinc.com,
charlie@...osinc.com,
masahiroy@...nel.org,
valentina.fernandezalanis@...rochip.com,
jassisinghbrar@...il.com,
conor.dooley@...rochip.com
Subject: [PATCH 2/3] riscv: crash: move IPI crash handling logic to crash.c
Move IPI crash handling code from smp.c to a new crash.c to
separate concerns and improve code organization, no functional change.
Signed-off-by: Yunhui Cui <cuiyunhui@...edance.com>
---
arch/riscv/include/asm/crash.h | 16 ++++++
arch/riscv/include/asm/smp.h | 14 +++++
arch/riscv/kernel/Makefile | 2 +-
arch/riscv/kernel/crash.c | 84 +++++++++++++++++++++++++++++
arch/riscv/kernel/smp.c | 99 +---------------------------------
5 files changed, 117 insertions(+), 98 deletions(-)
create mode 100644 arch/riscv/include/asm/crash.h
create mode 100644 arch/riscv/kernel/crash.c
diff --git a/arch/riscv/include/asm/crash.h b/arch/riscv/include/asm/crash.h
new file mode 100644
index 0000000000000..b64df919277d4
--- /dev/null
+++ b/arch/riscv/include/asm/crash.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef _ASM_RISC_V_CRASH_H
+#define _ASM_RISC_V_CRASH_H
+
+#ifdef CONFIG_KEXEC_CORE
+void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs);
+#else
+static inline void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
+{
+ unreachable();
+}
+#endif
+
+#endif
+
diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h
index 7ac80e9f22889..ffd7f6f8d25aa 100644
--- a/arch/riscv/include/asm/smp.h
+++ b/arch/riscv/include/asm/smp.h
@@ -12,6 +12,18 @@
#define INVALID_HARTID ULONG_MAX
+enum ipi_message_type {
+ IPI_RESCHEDULE,
+ IPI_CALL_FUNC,
+ IPI_CPU_STOP,
+ IPI_CPU_CRASH_STOP,
+ IPI_IRQ_WORK,
+ IPI_TIMER,
+ IPI_CPU_BACKTRACE,
+ IPI_KGDB_ROUNDUP,
+ IPI_MAX
+};
+
struct seq_file;
extern unsigned long boot_cpu_hartid;
@@ -51,6 +63,8 @@ bool riscv_ipi_have_virq_range(void);
/* Set the IPI interrupt numbers for arch (called by irqchip drivers) */
void riscv_ipi_set_virq_range(int virq, int nr);
+void send_ipi_mask(const struct cpumask *mask, enum ipi_message_type op);
+
/* Check other CPUs stop or not */
bool smp_crash_stop_failed(void);
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 16637e01a6b34..f0fd655b113d3 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -107,7 +107,7 @@ endif
obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o
obj-$(CONFIG_PARAVIRT) += paravirt.o
obj-$(CONFIG_KGDB) += kgdb.o
-obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o
+obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o crash.o
obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o kexec_image.o machine_kexec_file.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
diff --git a/arch/riscv/kernel/crash.c b/arch/riscv/kernel/crash.c
new file mode 100644
index 0000000000000..12598bbc2df04
--- /dev/null
+++ b/arch/riscv/kernel/crash.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/kexec.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+
+#include <asm/cpu_ops.h>
+
+static atomic_t waiting_for_crash_ipi = ATOMIC_INIT(0);
+
+inline void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
+{
+ crash_save_cpu(regs, cpu);
+
+ atomic_dec(&waiting_for_crash_ipi);
+
+ local_irq_disable();
+
+#ifdef CONFIG_HOTPLUG_CPU
+ if (cpu_has_hotplug(cpu))
+ cpu_ops->cpu_stop();
+#endif
+
+ for (;;)
+ wait_for_interrupt();
+}
+
+/*
+ * The number of CPUs online, not counting this CPU (which may not be
+ * fully online and so not counted in num_online_cpus()).
+ */
+static inline unsigned int num_other_online_cpus(void)
+{
+ unsigned int this_cpu_online = cpu_online(smp_processor_id());
+
+ return num_online_cpus() - this_cpu_online;
+}
+
+void crash_smp_send_stop(void)
+{
+ static int cpus_stopped;
+ cpumask_t mask;
+ unsigned long timeout;
+
+ /*
+ * This function can be called twice in panic path, but obviously
+ * we execute this only once.
+ */
+ if (cpus_stopped)
+ return;
+
+ cpus_stopped = 1;
+
+ /*
+ * If this cpu is the only one alive at this point in time, online or
+ * not, there are no stop messages to be sent around, so just back out.
+ */
+ if (num_other_online_cpus() == 0)
+ return;
+
+ cpumask_copy(&mask, cpu_online_mask);
+ cpumask_clear_cpu(smp_processor_id(), &mask);
+
+ atomic_set(&waiting_for_crash_ipi, num_other_online_cpus());
+
+ pr_crit("SMP: stopping secondary CPUs\n");
+ send_ipi_mask(&mask, IPI_CPU_CRASH_STOP);
+
+ /* Wait up to one second for other CPUs to stop */
+ timeout = USEC_PER_SEC;
+ while ((atomic_read(&waiting_for_crash_ipi) > 0) && timeout--)
+ udelay(1);
+
+ if (atomic_read(&waiting_for_crash_ipi) > 0)
+ pr_warn("SMP: failed to stop secondary CPUs %*pbl\n",
+ cpumask_pr_args(&mask));
+}
+
+bool smp_crash_stop_failed(void)
+{
+ return (atomic_read(&waiting_for_crash_ipi) > 0);
+}
diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index e650dec448176..c4191b15b3547 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -24,22 +24,11 @@
#include <linux/irq_work.h>
#include <linux/nmi.h>
+#include <asm/crash.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
#include <asm/cpu_ops.h>
-enum ipi_message_type {
- IPI_RESCHEDULE,
- IPI_CALL_FUNC,
- IPI_CPU_STOP,
- IPI_CPU_CRASH_STOP,
- IPI_IRQ_WORK,
- IPI_TIMER,
- IPI_CPU_BACKTRACE,
- IPI_KGDB_ROUNDUP,
- IPI_MAX
-};
-
unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = {
[0 ... NR_CPUS-1] = INVALID_HARTID
};
@@ -75,33 +64,7 @@ static void ipi_stop(void)
wait_for_interrupt();
}
-#ifdef CONFIG_KEXEC_CORE
-static atomic_t waiting_for_crash_ipi = ATOMIC_INIT(0);
-
-static inline void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
-{
- crash_save_cpu(regs, cpu);
-
- atomic_dec(&waiting_for_crash_ipi);
-
- local_irq_disable();
-
-#ifdef CONFIG_HOTPLUG_CPU
- if (cpu_has_hotplug(cpu))
- cpu_ops->cpu_stop();
-#endif
-
- for(;;)
- wait_for_interrupt();
-}
-#else
-static inline void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
-{
- unreachable();
-}
-#endif
-
-static void send_ipi_mask(const struct cpumask *mask, enum ipi_message_type op)
+void send_ipi_mask(const struct cpumask *mask, enum ipi_message_type op)
{
__ipi_send_mask(ipi_desc[op], mask);
}
@@ -276,64 +239,6 @@ void smp_send_stop(void)
cpumask_pr_args(cpu_online_mask));
}
-#ifdef CONFIG_KEXEC_CORE
-/*
- * The number of CPUs online, not counting this CPU (which may not be
- * fully online and so not counted in num_online_cpus()).
- */
-static inline unsigned int num_other_online_cpus(void)
-{
- unsigned int this_cpu_online = cpu_online(smp_processor_id());
-
- return num_online_cpus() - this_cpu_online;
-}
-
-void crash_smp_send_stop(void)
-{
- static int cpus_stopped;
- cpumask_t mask;
- unsigned long timeout;
-
- /*
- * This function can be called twice in panic path, but obviously
- * we execute this only once.
- */
- if (cpus_stopped)
- return;
-
- cpus_stopped = 1;
-
- /*
- * If this cpu is the only one alive at this point in time, online or
- * not, there are no stop messages to be sent around, so just back out.
- */
- if (num_other_online_cpus() == 0)
- return;
-
- cpumask_copy(&mask, cpu_online_mask);
- cpumask_clear_cpu(smp_processor_id(), &mask);
-
- atomic_set(&waiting_for_crash_ipi, num_other_online_cpus());
-
- pr_crit("SMP: stopping secondary CPUs\n");
- send_ipi_mask(&mask, IPI_CPU_CRASH_STOP);
-
- /* Wait up to one second for other CPUs to stop */
- timeout = USEC_PER_SEC;
- while ((atomic_read(&waiting_for_crash_ipi) > 0) && timeout--)
- udelay(1);
-
- if (atomic_read(&waiting_for_crash_ipi) > 0)
- pr_warn("SMP: failed to stop secondary CPUs %*pbl\n",
- cpumask_pr_args(&mask));
-}
-
-bool smp_crash_stop_failed(void)
-{
- return (atomic_read(&waiting_for_crash_ipi) > 0);
-}
-#endif
-
void arch_smp_send_reschedule(int cpu)
{
send_ipi_single(cpu, IPI_RESCHEDULE);
--
2.39.5
Powered by blists - more mailing lists