@@ -748,6 +748,13 @@ 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.
+ */
+ if (cpumask_test_cpu(smp_processor_id(), mask) && irqs_disabled())
+ nmi_cpu_backtrace(NULL);
+
smp_cross_call(mask, IPI_CPU_BACKTRACE);
}
@@ -149,7 +149,10 @@ bool nmi_cpu_backtrace(struct pt_regs *regs)
/* Replace printk to write into the NMI seq */
this_cpu_write(printk_func, nmi_vprintk);
pr_warn("NMI backtrace for cpu %d\n", cpu);
- show_regs(regs);
+ if (regs)
+ show_regs(regs);
+ else
+ dump_stack();
this_cpu_write(printk_func, printk_func_save);
cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
Currently on ARM when <SysRq-L> is triggered from an interrupt handler (e.g. a SysRq issued using UART or kbd) the main CPU will wedge for ten seconds with interrupts masked before issuing a backtrace for every CPU except itself. The new backtrace code introduced by commit 96f0e00378d4 ("ARM: add basic support for on-demand backtrace of other CPUs") does not work correctly when run from an interrupt handler because IPI_CPU_BACKTRACE is used to generate the backtrace on all CPUs but cannot preempt the current calling context. This can be fixed by detecting that the calling context cannot be preempted and issuing the backtrace directly in this case. Some small changes to the generic code are required to support this. Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> --- arch/arm/kernel/smp.c | 7 +++++++ lib/nmi_backtrace.c | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) -- 2.4.3