nmi_backtrace: do a local dump_stack() instead of a self-NMI
authorChris Metcalf <cmetcalf@mellanox.com>
Sat, 10 Sep 2016 10:34:18 +0000 (20:34 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Sat, 10 Sep 2016 10:34:18 +0000 (20:34 +1000)
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>
arch/arm/kernel/smp.c
lib/nmi_backtrace.c

index 2a367b2de0e14072e02f02dc908205450296a683..173ad30c20e0f7d4c6a402b82b532de8f6ca28a8 100644 (file)
@@ -748,15 +748,6 @@ core_initcall(register_cpufreq_notifier);
 
 static void raise_nmi(cpumask_t *mask)
 {
-       /*
-        * Generate the backtrace directly if we are running in a calling
-        * context that is not preemptible by the backtrace IPI. Note
-        * that nmi_cpu_backtrace() automatically removes the current cpu
-        * from mask.
-        */
-       if (cpumask_test_cpu(smp_processor_id(), mask) && irqs_disabled())
-               nmi_cpu_backtrace(NULL);
-
        smp_cross_call(mask, IPI_CPU_BACKTRACE);
 }
 
index df347e355267b176330aabc746b88787032e88e3..393a3cca1f47660e436131e6dbcf718d125ff6bb 100644 (file)
@@ -49,6 +49,15 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
        if (exclude_self)
                cpumask_clear_cpu(this_cpu, to_cpumask(backtrace_mask));
 
+       /*
+        * Don't try to send an NMI to this cpu; it may work on some
+        * architectures, but on others it may not, and we'll get
+        * information at least as useful just by doing a dump_stack() here.
+        * Note that nmi_cpu_backtrace(NULL) will clear the cpu bit.
+        */
+       if (cpumask_test_cpu(this_cpu, to_cpumask(backtrace_mask)))
+               nmi_cpu_backtrace(NULL);
+
        if (!cpumask_empty(to_cpumask(backtrace_mask))) {
                pr_info("Sending NMI from CPU %d to CPUs %*pbl:\n",
                        this_cpu, nr_cpumask_bits, to_cpumask(backtrace_mask));
This page took 0.026454 seconds and 5 git commands to generate.