Subject: + nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current.patch added to -mm tree To: atomlin@xxxxxxxxxx,davem@xxxxxxxxxxxxx,dzickus@xxxxxxxxxx,mguzik@xxxxxxxxxx,oleg@xxxxxxxxxx From: akpm@xxxxxxxxxxxxxxxxxxxx Date: Wed, 23 Apr 2014 14:14:12 -0700 The patch titled Subject: nmi: provide the option to issue an NMI back trace to every cpu but current has been added to the -mm tree. Its filename is nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Aaron Tomlin <atomlin@xxxxxxxxxx> Subject: nmi: provide the option to issue an NMI back trace to every cpu but current Sometimes it is preferred not to use the trigger_all_cpu_backtrace() routine when one wants to avoid capturing a back trace for current. For instance if one was previously captured recently. This patch provides a new routine namely trigger_allbutself_cpu_backtrace() which offers the flexibility to issue an NMI to every cpu but current and capture a back trace accordingly. Patch x86 and sparc to support new routine. [dzickus@xxxxxxxxxx: add stub in #else clause] [dzickus@xxxxxxxxxx: don't print message in single processor case, wrap with get/put_cpu based on Oleg's suggestion] Signed-off-by: Aaron Tomlin <atomlin@xxxxxxxxxx> Signed-off-by: Don Zickus <dzickus@xxxxxxxxxx> Acked-by: David S. Miller <davem@xxxxxxxxxxxxx> Cc: Mateusz Guzik <mguzik@xxxxxxxxxx> Cc: Oleg Nesterov <oleg@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- arch/sparc/include/asm/irq_64.h | 2 +- arch/sparc/kernel/process_64.c | 14 +++++++++----- arch/x86/include/asm/irq.h | 2 +- arch/x86/kernel/apic/hw_nmi.c | 17 +++++++++++++---- include/linux/nmi.h | 11 ++++++++++- 5 files changed, 34 insertions(+), 12 deletions(-) diff -puN arch/sparc/include/asm/irq_64.h~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current arch/sparc/include/asm/irq_64.h --- a/arch/sparc/include/asm/irq_64.h~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current +++ a/arch/sparc/include/asm/irq_64.h @@ -89,7 +89,7 @@ static inline unsigned long get_softint( return retval; } -void arch_trigger_all_cpu_backtrace(void); +void arch_trigger_all_cpu_backtrace(bool); #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace extern void *hardirq_stack[NR_CPUS]; diff -puN arch/sparc/kernel/process_64.c~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current arch/sparc/kernel/process_64.c --- a/arch/sparc/kernel/process_64.c~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current +++ a/arch/sparc/kernel/process_64.c @@ -239,7 +239,7 @@ static void __global_reg_poll(struct glo } } -void arch_trigger_all_cpu_backtrace(void) +void arch_trigger_all_cpu_backtrace(bool include_self) { struct thread_info *tp = current_thread_info(); struct pt_regs *regs = get_irq_regs(); @@ -251,15 +251,19 @@ void arch_trigger_all_cpu_backtrace(void spin_lock_irqsave(&global_cpu_snapshot_lock, flags); - memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot)); - this_cpu = raw_smp_processor_id(); - __global_reg_self(tp, regs, this_cpu); + memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot)); + + if (include_self) + __global_reg_self(tp, regs, this_cpu); smp_fetch_global_regs(); for_each_online_cpu(cpu) { + if (!include_self && cpu == this_cpu) + continue; + struct global_reg_snapshot *gp = &global_cpu_snapshot[cpu].reg; __global_reg_poll(gp); @@ -292,7 +296,7 @@ void arch_trigger_all_cpu_backtrace(void static void sysrq_handle_globreg(int key) { - arch_trigger_all_cpu_backtrace(); + arch_trigger_all_cpu_backtrace(true); } static struct sysrq_key_op sparc_globalreg_op = { diff -puN arch/x86/include/asm/irq.h~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current arch/x86/include/asm/irq.h --- a/arch/x86/include/asm/irq.h~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current +++ a/arch/x86/include/asm/irq.h @@ -43,7 +43,7 @@ extern int vector_used_by_percpu_irq(uns extern void init_ISA_irqs(void); #ifdef CONFIG_X86_LOCAL_APIC -void arch_trigger_all_cpu_backtrace(void); +void arch_trigger_all_cpu_backtrace(bool); #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace #endif diff -puN arch/x86/kernel/apic/hw_nmi.c~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current arch/x86/kernel/apic/hw_nmi.c --- a/arch/x86/kernel/apic/hw_nmi.c~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current +++ a/arch/x86/kernel/apic/hw_nmi.c @@ -33,31 +33,40 @@ static DECLARE_BITMAP(backtrace_mask, NR /* "in progress" flag of arch_trigger_all_cpu_backtrace */ static unsigned long backtrace_flag; -void arch_trigger_all_cpu_backtrace(void) +void arch_trigger_all_cpu_backtrace(bool include_self) { int i; + int cpu = get_cpu(); - if (test_and_set_bit(0, &backtrace_flag)) + if (test_and_set_bit(0, &backtrace_flag)) { /* * If there is already a trigger_all_cpu_backtrace() in progress * (backtrace_flag == 1), don't output double cpu dump infos. */ + put_cpu(); return; + } cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask); + if (!include_self) + cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); - printk(KERN_INFO "sending NMI to all CPUs:\n"); - apic->send_IPI_all(NMI_VECTOR); + if (!cpumask_empty(to_cpumask(backtrace_mask))) { + pr_info("sending NMI to %s CPUs:\n", (include_self ? "all" : "other")); + apic->send_IPI_mask(to_cpumask(backtrace_mask), NMI_VECTOR); + } /* 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(); } clear_bit(0, &backtrace_flag); smp_mb__after_clear_bit(); + put_cpu(); } static int __kprobes diff -puN include/linux/nmi.h~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current include/linux/nmi.h --- a/include/linux/nmi.h~nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current +++ a/include/linux/nmi.h @@ -32,15 +32,24 @@ static inline void touch_nmi_watchdog(vo #ifdef arch_trigger_all_cpu_backtrace static inline bool trigger_all_cpu_backtrace(void) { - arch_trigger_all_cpu_backtrace(); + arch_trigger_all_cpu_backtrace(true); return true; } +static inline bool trigger_allbutself_cpu_backtrace(void) +{ + arch_trigger_all_cpu_backtrace(false); + return true; +} #else static inline bool trigger_all_cpu_backtrace(void) { return false; } +static inline bool trigger_allbutself_cpu_backtrace(void) +{ + return false; +} #endif #ifdef CONFIG_LOCKUP_DETECTOR _ Patches currently in -mm which might be from atomlin@xxxxxxxxxx are nmi-provide-the-option-to-issue-an-nmi-back-trace-to-every-cpu-but-current.patch kernel-watchdogc-print-traces-for-all-cpus-on-lockup-detection.patch kernel-watchdogc-print-traces-for-all-cpus-on-lockup-detection-fix.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html