aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDon Zickus <dzickus@redhat.com>2010-05-07 17:11:48 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2010-05-12 17:55:47 -0400
commit7cbb7e7fa46f6e5229438ac9e4a5c72ec0d53e0b (patch)
tree6caea91476f1cf24dffc23822bcaf1b0b45b451e /arch
parentf69bcf60c3f17aa367e16eef7bc6ab001ea6d58a (diff)
x86: Move trigger_all_cpu_backtrace to its own die_notifier
As part of the transition of the nmi watchdog to something more generic, the trigger_all_cpu_backtrace code is getting left behind. Put it in its own die_notifier so it can still be used. V2: - use arch_spin_locks Signed-off-by: Don Zickus <dzickus@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Cyrill Gorcunov <gorcunov@gmail.com> Cc: Eric Paris <eparis@redhat.com> Cc: Randy Dunlap <randy.dunlap@oracle.com> LKML-Reference: <1273266711-18706-6-git-send-email-dzickus@redhat.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/apic/hw_nmi.c65
1 files changed, 51 insertions, 14 deletions
diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c
index 79425f96fcee..8c3edfb89c2b 100644
--- a/arch/x86/kernel/apic/hw_nmi.c
+++ b/arch/x86/kernel/apic/hw_nmi.c
@@ -17,6 +17,10 @@
17#include <linux/cpumask.h> 17#include <linux/cpumask.h>
18#include <linux/kernel_stat.h> 18#include <linux/kernel_stat.h>
19#include <asm/mce.h> 19#include <asm/mce.h>
20#include <linux/kdebug.h>
21#include <linux/notifier.h>
22#include <linux/kprobes.h>
23
20 24
21#include <linux/nmi.h> 25#include <linux/nmi.h>
22#include <linux/module.h> 26#include <linux/module.h>
@@ -54,20 +58,6 @@ int hw_nmi_is_cpu_stuck(struct pt_regs *regs)
54 unsigned int sum; 58 unsigned int sum;
55 int cpu = smp_processor_id(); 59 int cpu = smp_processor_id();
56 60
57 /* FIXME: cheap hack for this check, probably should get its own
58 * die_notifier handler
59 */
60 if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
61 static DEFINE_SPINLOCK(lock); /* Serialise the printks */
62
63 spin_lock(&lock);
64 printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
65 show_regs(regs);
66 dump_stack();
67 spin_unlock(&lock);
68 cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
69 }
70
71 /* if we are doing an mce, just assume the cpu is not stuck */ 61 /* if we are doing an mce, just assume the cpu is not stuck */
72 /* Could check oops_in_progress here too, but it's safer not to */ 62 /* Could check oops_in_progress here too, but it's safer not to */
73 if (mce_in_progress()) 63 if (mce_in_progress())
@@ -109,6 +99,53 @@ void arch_trigger_all_cpu_backtrace(void)
109 mdelay(1); 99 mdelay(1);
110 } 100 }
111} 101}
102
103static int __kprobes
104arch_trigger_all_cpu_backtrace_handler(struct notifier_block *self,
105 unsigned long cmd, void *__args)
106{
107 struct die_args *args = __args;
108 struct pt_regs *regs;
109 int cpu = smp_processor_id();
110
111 switch (cmd) {
112 case DIE_NMI:
113 case DIE_NMI_IPI:
114 break;
115
116 default:
117 return NOTIFY_DONE;
118 }
119
120 regs = args->regs;
121
122 if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
123 static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED;
124
125 arch_spin_lock(&lock);
126 printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
127 show_regs(regs);
128 dump_stack();
129 arch_spin_unlock(&lock);
130 cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
131 return NOTIFY_STOP;
132 }
133
134 return NOTIFY_DONE;
135}
136
137static __read_mostly struct notifier_block backtrace_notifier = {
138 .notifier_call = arch_trigger_all_cpu_backtrace_handler,
139 .next = NULL,
140 .priority = 1
141};
142
143static int __init register_trigger_all_cpu_backtrace(void)
144{
145 register_die_notifier(&backtrace_notifier);
146 return 0;
147}
148early_initcall(register_trigger_all_cpu_backtrace);
112#endif 149#endif
113 150
114/* STUB calls to mimic old nmi_watchdog behaviour */ 151/* STUB calls to mimic old nmi_watchdog behaviour */