Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nmi_backtrace: do a local dump_stack() instead of a self-NMI

Currently on arm there is code that checks whether it should call
dump_stack() explicitly, to avoid trying to raise an NMI when the
current context is not preemptible by the backtrace IPI. Similarly, the
forthcoming arch/tile support uses an IPI mechanism that does not
support generating an NMI to self.

Accordingly, move the code that guards this case into the generic
mechanism, and invoke it unconditionally whenever we want a backtrace of
the current cpu. It seems plausible that in all cases, dump_stack()
will generate better information than generating a stack from the NMI
handler. The register state will be missing, but that state is likely
not particularly helpful in any case.

Or, if we think it is helpful, we should be capturing and emitting the
current register state in all cases when regs == NULL is passed to
nmi_cpu_backtrace().

Link: http://lkml.kernel.org/r/1472487169-14923-3-git-send-email-cmetcalf@mellanox.com
Signed-off-by: Chris Metcalf <cmetcalf@mellanox.com>
Tested-by: Daniel Thompson <daniel.thompson@linaro.org> [arm]
Reviewed-by: Petr Mladek <pmladek@suse.com>
Acked-by: Aaron Tomlin <atomlin@redhat.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Chris Metcalf and committed by
Linus Torvalds
67766489 9a01c3ed

+9 -9
-9
arch/arm/kernel/smp.c
··· 748 748 749 749 static void raise_nmi(cpumask_t *mask) 750 750 { 751 - /* 752 - * Generate the backtrace directly if we are running in a calling 753 - * context that is not preemptible by the backtrace IPI. Note 754 - * that nmi_cpu_backtrace() automatically removes the current cpu 755 - * from mask. 756 - */ 757 - if (cpumask_test_cpu(smp_processor_id(), mask) && irqs_disabled()) 758 - nmi_cpu_backtrace(NULL); 759 - 760 751 smp_cross_call(mask, IPI_CPU_BACKTRACE); 761 752 } 762 753
+9
lib/nmi_backtrace.c
··· 49 49 if (exclude_self) 50 50 cpumask_clear_cpu(this_cpu, to_cpumask(backtrace_mask)); 51 51 52 + /* 53 + * Don't try to send an NMI to this cpu; it may work on some 54 + * architectures, but on others it may not, and we'll get 55 + * information at least as useful just by doing a dump_stack() here. 56 + * Note that nmi_cpu_backtrace(NULL) will clear the cpu bit. 57 + */ 58 + if (cpumask_test_cpu(this_cpu, to_cpumask(backtrace_mask))) 59 + nmi_cpu_backtrace(NULL); 60 + 52 61 if (!cpumask_empty(to_cpumask(backtrace_mask))) { 53 62 pr_info("Sending NMI from CPU %d to CPUs %*pbl:\n", 54 63 this_cpu, nr_cpumask_bits, to_cpumask(backtrace_mask));