From: Aaron Tomlin <atomlin@atomlin.com>
To: pmladek@suse.com, john.ogness@linutronix.de, rostedt@goodmis.org,
senozhatsky@chromium.org, mingo@redhat.com, peterz@infradead.org,
juri.lelli@redhat.com, vincent.guittot@linaro.org,
dietmar.eggemann@arm.com, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kprateek.nayak@amd.com,
akpm@linux-foundation.org, baoquan.he@linux.dev, rppt@kernel.org,
pasha.tatashin@soleen.com, pratyush@kernel.org,
ruirui.yang@linux.dev, david@kernel.org, ljs@kernel.org,
liam@infradead.org, vbabka@kernel.org, surenb@google.com,
mhocko@suse.com, kees@kernel.org, anna-maria@linutronix.de,
frederic@kernel.org, tglx@kernel.org, mhiramat@kernel.org,
mathieu.desnoyers@efficios.com, brendan.jackman@linux.dev,
hannes@cmpxchg.org, ziy@nvidia.com, bigeasy@linutronix.de,
clrkwllms@kernel.org
Cc: linux-kernel@vger.kernel.org, kexec@lists.infradead.org,
linux-mm@kvack.org, linux-trace-kernel@vger.kernel.org,
linux-rt-devel@lists.linux.dev
Subject: [RFC PATCH v2 1/5] panic, sys_info: Fix duplicate and dropped all-CPU backtraces in panic
Date: Mon, 2 Nov 2026 21:44:49 -0500 [thread overview]
Message-ID: <20261103024453.922373-2-atomlin@atomlin.com> (raw)
In-Reply-To: <20261103024453.922373-1-atomlin@atomlin.com>
When sys_info() was factored out of kernel/panic.c by
commit b76e89e50fc3 ("panic: generalize panic_print's function to show
sys info"), __sys_info() gained an unconditional call to
trigger_all_cpu_backtrace() when SYS_INFO_ALL_BT is set, while
panic_other_cpus_shutdown() retained its own call to
panic_trigger_all_cpu_backtrace().
This causes two problems during a kernel panic:
1. vpanic() invokes panic_trigger_all_cpu_backtrace() inside
panic_other_cpus_shutdown() before stopping secondary CPUs, and
then invokes trigger_all_cpu_backtrace() a second time inside
sys_info(panic_print) after secondary CPUs have already been
shut down, stalling for up to 10 seconds waiting for offline
CPUs to respond to NMIs. Furthermore, if SYS_INFO_ALL_BT is
configured via the kernel.kernel_sys_info sysctl rather than
panic_print, panic_other_cpus_shutdown() misses it prior to CPU
shutdown.
2. If sys_info(SYS_INFO_ALL_BT) is invoked on the panicking CPU
prior to panic_other_cpus_shutdown(), calling
trigger_all_cpu_backtrace() directly bypasses
panic_trigger_all_cpu_backtrace() and leaves
panic_triggering_all_cpu_backtrace unset. Because panic_cpu is
already active, vprintk_emit() silently drops all NMI backtrace
messages originating from non-panic CPUs.
Export panic_trigger_all_cpu_backtrace() with a panic_on_this_cpu() and
one-shot guard so all-CPU backtraces are only emitted once before
secondary CPUs are stopped, consult sys_info_get_mask(panic_print) in
panic_other_cpus_shutdown(), record prior Oops stack dumps in
panic_try_start(), and route SYS_INFO_ALL_BT in __sys_info()
through panic_trigger_all_cpu_backtrace() on the panicking CPU.
Fixes: b76e89e50fc3 ("panic: generalize panic_print's function to show sys info")
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
include/linux/panic.h | 1 +
include/linux/sys_info.h | 1 +
kernel/panic.c | 31 +++++++++++++++++++++++++++----
lib/sys_info.c | 17 ++++++++++++++---
4 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/include/linux/panic.h b/include/linux/panic.h
index 17e61b61c45f..3b56f873f1e2 100644
--- a/include/linux/panic.h
+++ b/include/linux/panic.h
@@ -57,6 +57,7 @@ void panic_reset(void);
bool panic_in_progress(void);
bool panic_on_this_cpu(void);
bool panic_on_other_cpu(void);
+void panic_trigger_all_cpu_backtrace(void);
/*
* Only to be used by arch init code. If the user over-wrote the default
diff --git a/include/linux/sys_info.h b/include/linux/sys_info.h
index a5bc3ea3d44b..e7699b82aa49 100644
--- a/include/linux/sys_info.h
+++ b/include/linux/sys_info.h
@@ -18,6 +18,7 @@
#define SYS_INFO_BLOCKED_TASKS 0x00000080
void sys_info(unsigned long si_mask);
+unsigned long sys_info_get_mask(unsigned long si_mask);
unsigned long sys_info_parse_param(char *str);
#ifdef CONFIG_SYSCTL
diff --git a/kernel/panic.c b/kernel/panic.c
index 574ee5a12f92..4cb26914b2af 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -70,6 +70,7 @@ static bool panic_console_replay;
bool panic_triggering_all_cpu_backtrace;
static bool panic_this_cpu_backtrace_printed;
+static bool panic_all_cpu_backtrace_printed;
int panic_timeout = CONFIG_PANIC_TIMEOUT;
EXPORT_SYMBOL_GPL(panic_timeout);
@@ -451,13 +452,21 @@ bool panic_try_start(void)
old_cpu = PANIC_CPU_INVALID;
this_cpu = raw_smp_processor_id();
- return atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu);
+ if (!atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu))
+ return false;
+
+ if (atomic_read(&panic_redirect_cpu) == PANIC_CPU_INVALID &&
+ (test_taint(TAINT_DIE) || oops_in_progress))
+ panic_this_cpu_backtrace_printed = true;
+
+ return true;
}
EXPORT_SYMBOL(panic_try_start);
void panic_reset(void)
{
- atomic_set(&panic_cpu, PANIC_CPU_INVALID);
+ panic_this_cpu_backtrace_printed = false;
+ atomic_set_release(&panic_cpu, PANIC_CPU_INVALID);
}
EXPORT_SYMBOL(panic_reset);
@@ -538,8 +547,21 @@ void check_panic_on_warn(const char *origin)
origin, limit);
}
-static void panic_trigger_all_cpu_backtrace(void)
+/**
+ * panic_trigger_all_cpu_backtrace - trigger NMI backtraces on all CPUs once
+ *
+ * Temporarily permit non-panic CPUs to emit messages into the printk ring
+ * buffer while capturing all-CPU backtraces during a panic. Subsequent calls
+ * are ignored so backtraces are not re-triggered after secondary CPUs have
+ * been shut down.
+ */
+void panic_trigger_all_cpu_backtrace(void)
{
+ if (!panic_on_this_cpu() || panic_all_cpu_backtrace_printed)
+ return;
+
+ panic_all_cpu_backtrace_printed = true;
+
/* Temporary allow non-panic CPUs to write their backtraces. */
panic_triggering_all_cpu_backtrace = true;
@@ -558,8 +580,9 @@ static void panic_trigger_all_cpu_backtrace(void)
*/
static void panic_other_cpus_shutdown(bool crash_kexec)
{
- if (panic_print & SYS_INFO_ALL_BT)
+ if (sys_info_get_mask(panic_print) & SYS_INFO_ALL_BT)
panic_trigger_all_cpu_backtrace();
+ panic_all_cpu_backtrace_printed = true;
/*
* Note that smp_send_stop() is the usual SMP shutdown function,
diff --git a/lib/sys_info.c b/lib/sys_info.c
index f32a06ec9ed4..496893eb776b 100644
--- a/lib/sys_info.c
+++ b/lib/sys_info.c
@@ -7,6 +7,7 @@
#include <linux/kernel.h>
#include <linux/ftrace.h>
#include <linux/nmi.h>
+#include <linux/panic.h>
#include <linux/sched/debug.h>
#include <linux/string.h>
#include <linux/sysctl.h>
@@ -153,14 +154,24 @@ static void __sys_info(unsigned long si_mask)
if (si_mask & SYS_INFO_FTRACE)
ftrace_dump(DUMP_ALL);
- if (si_mask & SYS_INFO_ALL_BT)
- trigger_all_cpu_backtrace();
+ if (si_mask & SYS_INFO_ALL_BT) {
+ if (panic_on_this_cpu())
+ panic_trigger_all_cpu_backtrace();
+ else if (!panic_in_progress())
+ trigger_all_cpu_backtrace();
+ }
if (si_mask & SYS_INFO_BLOCKED_TASKS)
show_state_filter(TASK_UNINTERRUPTIBLE);
}
+unsigned long sys_info_get_mask(unsigned long si_mask)
+{
+ return (si_mask & ~SYS_INFO_PANIC_CONSOLE_REPLAY) ? :
+ READ_ONCE(kernel_si_mask);
+}
+
void sys_info(unsigned long si_mask)
{
- __sys_info(si_mask ? : kernel_si_mask);
+ __sys_info(sys_info_get_mask(si_mask));
}
--
2.55.0
next prev parent reply other threads:[~2026-11-03 2:45 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 2:44 [RFC PATCH v2 0/5] panic, crash_core, sys_info: Introduce crash_kexec_in_memory_sys_info Aaron Tomlin
2026-11-03 2:44 ` Aaron Tomlin [this message]
2026-11-03 2:44 ` [RFC PATCH v2 2/5] mm/show_mem: Avoid blocking on zone->lock during Oops or panic Aaron Tomlin
2026-11-03 2:44 ` [RFC PATCH v2 3/5] timers: Avoid blocking on hrtimer_cpu_base lock " Aaron Tomlin
2026-11-03 2:44 ` [RFC PATCH v2 4/5] printk, tracing: Support console flush suppression and tail pinning Aaron Tomlin
2026-11-03 14:55 ` Steven Rostedt
2026-11-03 15:49 ` Aaron Tomlin
2026-11-03 2:44 ` [RFC PATCH v2 5/5] panic, crash_core, sys_info: Introduce crash_kexec_in_memory_sys_info Aaron Tomlin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261103024453.922373-2-atomlin@atomlin.com \
--to=atomlin@atomlin.com \
--cc=akpm@linux-foundation.org \
--cc=anna-maria@linutronix.de \
--cc=baoquan.he@linux.dev \
--cc=bigeasy@linutronix.de \
--cc=brendan.jackman@linux.dev \
--cc=bsegall@google.com \
--cc=clrkwllms@kernel.org \
--cc=david@kernel.org \
--cc=dietmar.eggemann@arm.com \
--cc=frederic@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=john.ogness@linutronix.de \
--cc=juri.lelli@redhat.com \
--cc=kees@kernel.org \
--cc=kexec@lists.infradead.org \
--cc=kprateek.nayak@amd.com \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mgorman@suse.de \
--cc=mhiramat@kernel.org \
--cc=mhocko@suse.com \
--cc=mingo@redhat.com \
--cc=pasha.tatashin@soleen.com \
--cc=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=pratyush@kernel.org \
--cc=rostedt@goodmis.org \
--cc=rppt@kernel.org \
--cc=ruirui.yang@linux.dev \
--cc=senozhatsky@chromium.org \
--cc=surenb@google.com \
--cc=tglx@kernel.org \
--cc=vbabka@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®