diff options
author | Don Zickus <dzickus@redhat.com> | 2010-05-07 17:11:48 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2010-05-12 17:55:47 -0400 |
commit | 7cbb7e7fa46f6e5229438ac9e4a5c72ec0d53e0b (patch) | |
tree | 6caea91476f1cf24dffc23822bcaf1b0b45b451e /arch | |
parent | f69bcf60c3f17aa367e16eef7bc6ab001ea6d58a (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.c | 65 |
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 | |||
103 | static int __kprobes | ||
104 | arch_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 | |||
137 | static __read_mostly struct notifier_block backtrace_notifier = { | ||
138 | .notifier_call = arch_trigger_all_cpu_backtrace_handler, | ||
139 | .next = NULL, | ||
140 | .priority = 1 | ||
141 | }; | ||
142 | |||
143 | static int __init register_trigger_all_cpu_backtrace(void) | ||
144 | { | ||
145 | register_die_notifier(&backtrace_notifier); | ||
146 | return 0; | ||
147 | } | ||
148 | early_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 */ |