mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] lib/nmi_backtrace: print out the CPUs which fail to respond to NMI
@ 2026-05-21  3:03 Feng Tang
  2026-05-21 22:37 ` Andrew Morton
  0 siblings, 1 reply; 6+ messages in thread
From: Feng Tang @ 2026-05-21  3:03 UTC (permalink / raw)
  To: Andrew Morton, paulmck, Petr Mladek; +Cc: linux-kernel, Feng Tang

When debugging RCU stall cases, usually all CPUs will respond to the
NMI and print out the backtrace. But in some nasty or hardware related
cases, some CPUs may fail to respond in 10 seconds, and very likely
this is sign of severe issues.

Paul E. McKenney has implemented the NMI backtrace stall check for x86,
and for other architectures, it should be also helpful to at least
print out those CPUs which failed to repond to the NMI, so that users
can get an early heads-up for possible CPU hard stall.

Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
---
 lib/nmi_backtrace.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c
index 33c154264bfe..a113d3d669be 100644
--- a/lib/nmi_backtrace.c
+++ b/lib/nmi_backtrace.c
@@ -75,7 +75,13 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
 		mdelay(1);
 		touch_softlockup_watchdog();
 	}
-	nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
+
+	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
+		pr_warn("After 10 seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
+			cpumask_pr_args(to_cpumask(backtrace_mask)));
+
+		nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
+	}
 
 	/*
 	 * Force flush any remote buffers that might be stuck in IRQ context
-- 
2.39.5 (Apple Git-154)


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] lib/nmi_backtrace: print out the CPUs which fail to respond to NMI
  2026-05-21  3:03 [PATCH] lib/nmi_backtrace: print out the CPUs which fail to respond to NMI Feng Tang
@ 2026-05-21 22:37 ` Andrew Morton
  2026-05-22  1:46   ` Feng Tang
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Morton @ 2026-05-21 22:37 UTC (permalink / raw)
  To: Feng Tang; +Cc: paulmck, Petr Mladek, linux-kernel

On Thu, 21 May 2026 11:03:36 +0800 Feng Tang <feng.tang@linux.alibaba.com> wrote:

> When debugging RCU stall cases, usually all CPUs will respond to the
> NMI and print out the backtrace. But in some nasty or hardware related
> cases, some CPUs may fail to respond in 10 seconds, and very likely
> this is sign of severe issues.
> 
> Paul E. McKenney has implemented the NMI backtrace stall check for x86,
> and for other architectures, it should be also helpful to at least
> print out those CPUs which failed to repond to the NMI, so that users
> can get an early heads-up for possible CPU hard stall.

That must be one messed up machine.  Is this something you've
encountered in real life?

> --- a/lib/nmi_backtrace.c
> +++ b/lib/nmi_backtrace.c
> @@ -75,7 +75,13 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
>  		mdelay(1);
>  		touch_softlockup_watchdog();
>  	}
> -	nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
> +
> +	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
> +		pr_warn("After 10 seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
> +			cpumask_pr_args(to_cpumask(backtrace_mask)));
> +
> +		nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
> +	}

It's a nitpick, but

: 	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
: 	for (i = 0; i < 10 * 1000; i++) {
: 		if (cpumask_empty(to_cpumask(backtrace_mask)))
: 			break;
: 		mdelay(1);
: 		touch_softlockup_watchdog();
: 	}
: 
: 	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
: 		pr_warn("After 10 seconds, these CPUS still haven't responded to the NMI: %*pbl\n",

Here we're hard-coding "10" in two places and in a comment.  It would
be nicer to do

	#define FOO_TIMEOUT 10

then use that throughout.

(bonus points for figuring out how to paste that "10" into the
pr_warn() control string rather than using %d!)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] lib/nmi_backtrace: print out the CPUs which fail to respond to NMI
  2026-05-21 22:37 ` Andrew Morton
@ 2026-05-22  1:46   ` Feng Tang
  2026-05-22  3:53     ` Andrew Morton
  0 siblings, 1 reply; 6+ messages in thread
From: Feng Tang @ 2026-05-22  1:46 UTC (permalink / raw)
  To: Andrew Morton; +Cc: paulmck, Petr Mladek, linux-kernel

Hi Andrew,

Thanks for the review!

On Thu, May 21, 2026 at 03:37:16PM -0700, Andrew Morton wrote:
> On Thu, 21 May 2026 11:03:36 +0800 Feng Tang <feng.tang@linux.alibaba.com> wrote:
> 
> > When debugging RCU stall cases, usually all CPUs will respond to the
> > NMI and print out the backtrace. But in some nasty or hardware related
> > cases, some CPUs may fail to respond in 10 seconds, and very likely
> > this is sign of severe issues.
> > 
> > Paul E. McKenney has implemented the NMI backtrace stall check for x86,
> > and for other architectures, it should be also helpful to at least
> > print out those CPUs which failed to repond to the NMI, so that users
> > can get an early heads-up for possible CPU hard stall.
> 
> That must be one messed up machine.  Is this something you've
> encountered in real life?

Yes. A big parf of my worktime is to play with panic/lockup/rcustall/hung
bugs :). And we did see some real case, and if there is such warning, it
could have given us good hint to focus on the not-responding CPU. In one
case, kernel requested 31 CPUs to do the CPU backtrace, and only 30 CPUs
really did, while the left unnoticed CPU is the root cause.

> > --- a/lib/nmi_backtrace.c
> > +++ b/lib/nmi_backtrace.c
> > @@ -75,7 +75,13 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
> >  		mdelay(1);
> >  		touch_softlockup_watchdog();
> >  	}
> > -	nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
> > +
> > +	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
> > +		pr_warn("After 10 seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
> > +			cpumask_pr_args(to_cpumask(backtrace_mask)));
> > +
> > +		nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
> > +	}
> 
> It's a nitpick, but
> 
> : 	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
> : 	for (i = 0; i < 10 * 1000; i++) {
> : 		if (cpumask_empty(to_cpumask(backtrace_mask)))
> : 			break;
> : 		mdelay(1);
> : 		touch_softlockup_watchdog();
> : 	}
> : 
> : 	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
> : 		pr_warn("After 10 seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
> 
> Here we're hard-coding "10" in two places and in a comment.  It would
> be nicer to do
> 
> 	#define FOO_TIMEOUT 10
> 
> then use that throughout.
> 
> (bonus points for figuring out how to paste that "10" into the
> pr_warn() control string rather than using %d!)

How about this followon patch?
---
diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c
index a113d3d669be..2810b8f478a4 100644
--- a/lib/nmi_backtrace.c
+++ b/lib/nmi_backtrace.c
@@ -27,6 +27,8 @@ static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly;
 /* "in progress" flag of arch_trigger_cpumask_backtrace */
 static unsigned long backtrace_flag;
 
+#define NMI_BT_TIMEOUT_SEC	10
+
 /*
  * When raise() is called it will be passed a pointer to the
  * backtrace_mask. Architectures that call nmi_cpu_backtrace()
@@ -68,8 +70,8 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
 		raise(to_cpumask(backtrace_mask));
 	}
 
-	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
-	for (i = 0; i < 10 * 1000; i++) {
+	/* Wait for up to NMI_BT_TIMEOUT_SEC seconds for all CPUs to do the backtrace */
+	for (i = 0; i < NMI_BT_TIMEOUT_SEC * 1000; i++) {
 		if (cpumask_empty(to_cpumask(backtrace_mask)))
 			break;
 		mdelay(1);
@@ -77,8 +79,8 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
 	}
 
 	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
-		pr_warn("After 10 seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
-			cpumask_pr_args(to_cpumask(backtrace_mask)));
+		pr_warn("After %d seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
+			NMI_BT_TIMEOUT_SEC, cpumask_pr_args(to_cpumask(backtrace_mask)));
 
 		nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
 	}



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] lib/nmi_backtrace: print out the CPUs which fail to respond to NMI
  2026-05-22  1:46   ` Feng Tang
@ 2026-05-22  3:53     ` Andrew Morton
  2026-05-22  5:02       ` Feng Tang
  2026-05-22  8:06       ` Petr Mladek
  0 siblings, 2 replies; 6+ messages in thread
From: Andrew Morton @ 2026-05-22  3:53 UTC (permalink / raw)
  To: Feng Tang; +Cc: paulmck, Petr Mladek, linux-kernel

On Fri, 22 May 2026 09:46:26 +0800 Feng Tang <feng.tang@linux.alibaba.com> wrote:

> > It's a nitpick, but
> > 
> > : 	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
> > : 	for (i = 0; i < 10 * 1000; i++) {
> > : 		if (cpumask_empty(to_cpumask(backtrace_mask)))
> > : 			break;
> > : 		mdelay(1);
> > : 		touch_softlockup_watchdog();
> > : 	}
> > : 
> > : 	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
> > : 		pr_warn("After 10 seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
> > 
> > Here we're hard-coding "10" in two places and in a comment.  It would
> > be nicer to do
> > 
> > 	#define FOO_TIMEOUT 10
> > 
> > then use that throughout.
> > 
> > (bonus points for figuring out how to paste that "10" into the
> > pr_warn() control string rather than using %d!)
> 
> How about this followon patch?

Looks great.  But you missed the fun part!

--- a/lib/nmi_backtrace.c~lib-nmi_backtrace-print-out-the-cpus-which-fail-to-respond-to-nmi-fix-fix
+++ a/lib/nmi_backtrace.c
@@ -16,6 +16,7 @@
 #include <linux/cpumask.h>
 #include <linux/delay.h>
 #include <linux/kprobes.h>
+#include <linux/stringify.h>
 #include <linux/nmi.h>
 #include <linux/cpu.h>
 #include <linux/sched/debug.h>
@@ -79,8 +80,8 @@ void nmi_trigger_cpumask_backtrace(const
 	}
 
 	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
-		pr_warn("After %d seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
-			NMI_BT_TIMEOUT_SEC, cpumask_pr_args(to_cpumask(backtrace_mask)));
+		pr_warn("After " __stringify(NMI_BT_TIMEOUT_SEC) " seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
+			cpumask_pr_args(to_cpumask(backtrace_mask)));
 
 		nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
 	}
_

It saved five bytes!



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] lib/nmi_backtrace: print out the CPUs which fail to respond to NMI
  2026-05-22  3:53     ` Andrew Morton
@ 2026-05-22  5:02       ` Feng Tang
  2026-05-22  8:06       ` Petr Mladek
  1 sibling, 0 replies; 6+ messages in thread
From: Feng Tang @ 2026-05-22  5:02 UTC (permalink / raw)
  To: Andrew Morton; +Cc: paulmck, Petr Mladek, linux-kernel

On Thu, May 21, 2026 at 08:53:26PM -0700, Andrew Morton wrote:
> 
> Looks great.  But you missed the fun part!
> 
> --- a/lib/nmi_backtrace.c~lib-nmi_backtrace-print-out-the-cpus-which-fail-to-respond-to-nmi-fix-fix
> +++ a/lib/nmi_backtrace.c
> @@ -16,6 +16,7 @@
>  #include <linux/cpumask.h>
>  #include <linux/delay.h>
>  #include <linux/kprobes.h>
> +#include <linux/stringify.h>
>  #include <linux/nmi.h>
>  #include <linux/cpu.h>
>  #include <linux/sched/debug.h>
> @@ -79,8 +80,8 @@ void nmi_trigger_cpumask_backtrace(const
>  	}
>  
>  	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
> -		pr_warn("After %d seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
> -			NMI_BT_TIMEOUT_SEC, cpumask_pr_args(to_cpumask(backtrace_mask)));
> +		pr_warn("After " __stringify(NMI_BT_TIMEOUT_SEC) " seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
> +			cpumask_pr_args(to_cpumask(backtrace_mask)));
>  
>  		nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
>  	}
> _
> 
> It saved five bytes!
 
Good to know :) Thanks for the trick!


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] lib/nmi_backtrace: print out the CPUs which fail to respond to NMI
  2026-05-22  3:53     ` Andrew Morton
  2026-05-22  5:02       ` Feng Tang
@ 2026-05-22  8:06       ` Petr Mladek
  1 sibling, 0 replies; 6+ messages in thread
From: Petr Mladek @ 2026-05-22  8:06 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Feng Tang, paulmck, linux-kernel

On Thu 2026-05-21 20:53:26, Andrew Morton wrote:
> On Fri, 22 May 2026 09:46:26 +0800 Feng Tang <feng.tang@linux.alibaba.com> wrote:
> 
> > > It's a nitpick, but
> > > 
> > > : 	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
> > > : 	for (i = 0; i < 10 * 1000; i++) {
> > > : 		if (cpumask_empty(to_cpumask(backtrace_mask)))
> > > : 			break;
> > > : 		mdelay(1);
> > > : 		touch_softlockup_watchdog();
> > > : 	}
> > > : 
> > > : 	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
> > > : 		pr_warn("After 10 seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
> > > 
> > > Here we're hard-coding "10" in two places and in a comment.  It would
> > > be nicer to do
> > > 
> > > 	#define FOO_TIMEOUT 10
> > > 
> > > then use that throughout.
> > > 
> > > (bonus points for figuring out how to paste that "10" into the
> > > pr_warn() control string rather than using %d!)
> > 
> > How about this followon patch?
> 
> Looks great.  But you missed the fun part!
> 
> --- a/lib/nmi_backtrace.c~lib-nmi_backtrace-print-out-the-cpus-which-fail-to-respond-to-nmi-fix-fix
> +++ a/lib/nmi_backtrace.c
> @@ -16,6 +16,7 @@
>  #include <linux/cpumask.h>
>  #include <linux/delay.h>
>  #include <linux/kprobes.h>
> +#include <linux/stringify.h>
>  #include <linux/nmi.h>
>  #include <linux/cpu.h>
>  #include <linux/sched/debug.h>
> @@ -79,8 +80,8 @@ void nmi_trigger_cpumask_backtrace(const
>  	}
>  
>  	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
> -		pr_warn("After %d seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
> -			NMI_BT_TIMEOUT_SEC, cpumask_pr_args(to_cpumask(backtrace_mask)));
> +		pr_warn("After " __stringify(NMI_BT_TIMEOUT_SEC) " seconds, these CPUS still haven't responded to the NMI: %*pbl\n",
> +			cpumask_pr_args(to_cpumask(backtrace_mask)));
>  
>  		nmi_backtrace_stall_check(to_cpumask(backtrace_mask));
>  	}
> _

With all the followup fixes, LGTM:

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-05-22  8:07 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-21  3:03 [PATCH] lib/nmi_backtrace: print out the CPUs which fail to respond to NMI Feng Tang
2026-05-21 22:37 ` Andrew Morton
2026-05-22  1:46   ` Feng Tang
2026-05-22  3:53     ` Andrew Morton
2026-05-22  5:02       ` Feng Tang
2026-05-22  8:06       ` Petr Mladek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome