diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-08-03 03:31:54 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-08-03 03:56:52 -0400 |
commit | 47cab6a722d44c71c4f8224017ef548522243cf4 (patch) | |
tree | 477bbe67a203d9704792d6ce46a9f1199587ddfe | |
parent | c1dc0b9c0c8979ce4d411caadff5c0d79dee58bc (diff) |
debug lockups: Improve lockup detection, fix generic arch fallback
As Andrew noted, my previous patch ("debug lockups: Improve lockup
detection") broke/removed SysRq-L support from architecture that do
not provide a __trigger_all_cpu_backtrace implementation.
Restore a fallback path and clean up the SysRq-L machinery a bit:
- Rename the arch method to arch_trigger_all_cpu_backtrace()
- Simplify the define
- Document the method a bit - in the hope of more architectures
adding support for it.
[ The patch touches Sparc code for the rename. ]
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: "David S. Miller" <davem@davemloft.net>
LKML-Reference: <20090802140809.7ec4bb6b.akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/sparc/include/asm/irq_64.h | 4 | ||||
-rw-r--r-- | arch/sparc/kernel/process_64.c | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/nmi.h | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic/nmi.c | 2 | ||||
-rw-r--r-- | drivers/char/sysrq.c | 15 | ||||
-rw-r--r-- | include/linux/nmi.h | 19 |
6 files changed, 38 insertions, 10 deletions
diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h index 1934f2cbf513..a0b443cb3c1f 100644 --- a/arch/sparc/include/asm/irq_64.h +++ b/arch/sparc/include/asm/irq_64.h | |||
@@ -89,8 +89,8 @@ static inline unsigned long get_softint(void) | |||
89 | return retval; | 89 | return retval; |
90 | } | 90 | } |
91 | 91 | ||
92 | void __trigger_all_cpu_backtrace(void); | 92 | void arch_trigger_all_cpu_backtrace(void); |
93 | #define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() | 93 | #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace |
94 | 94 | ||
95 | extern void *hardirq_stack[NR_CPUS]; | 95 | extern void *hardirq_stack[NR_CPUS]; |
96 | extern void *softirq_stack[NR_CPUS]; | 96 | extern void *softirq_stack[NR_CPUS]; |
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 4041f94e7724..18d67854a1b8 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -251,7 +251,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp) | |||
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
254 | void __trigger_all_cpu_backtrace(void) | 254 | void arch_trigger_all_cpu_backtrace(void) |
255 | { | 255 | { |
256 | struct thread_info *tp = current_thread_info(); | 256 | struct thread_info *tp = current_thread_info(); |
257 | struct pt_regs *regs = get_irq_regs(); | 257 | struct pt_regs *regs = get_irq_regs(); |
@@ -304,7 +304,7 @@ void __trigger_all_cpu_backtrace(void) | |||
304 | 304 | ||
305 | static void sysrq_handle_globreg(int key, struct tty_struct *tty) | 305 | static void sysrq_handle_globreg(int key, struct tty_struct *tty) |
306 | { | 306 | { |
307 | __trigger_all_cpu_backtrace(); | 307 | arch_trigger_all_cpu_backtrace(); |
308 | } | 308 | } |
309 | 309 | ||
310 | static struct sysrq_key_op sparc_globalreg_op = { | 310 | static struct sysrq_key_op sparc_globalreg_op = { |
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index c86e5ed4af51..e63cf7d441e1 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h | |||
@@ -45,8 +45,8 @@ extern int proc_nmi_enabled(struct ctl_table *, int , struct file *, | |||
45 | void __user *, size_t *, loff_t *); | 45 | void __user *, size_t *, loff_t *); |
46 | extern int unknown_nmi_panic; | 46 | extern int unknown_nmi_panic; |
47 | 47 | ||
48 | void __trigger_all_cpu_backtrace(void); | 48 | void arch_trigger_all_cpu_backtrace(void); |
49 | #define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() | 49 | #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace |
50 | 50 | ||
51 | static inline void localise_nmi_watchdog(void) | 51 | static inline void localise_nmi_watchdog(void) |
52 | { | 52 | { |
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index 1bb1ac20e9ec..db7220220d09 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c | |||
@@ -554,7 +554,7 @@ int do_nmi_callback(struct pt_regs *regs, int cpu) | |||
554 | return 0; | 554 | return 0; |
555 | } | 555 | } |
556 | 556 | ||
557 | void __trigger_all_cpu_backtrace(void) | 557 | void arch_trigger_all_cpu_backtrace(void) |
558 | { | 558 | { |
559 | int i; | 559 | int i; |
560 | 560 | ||
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 165f307f30e8..50eecfe1d724 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -223,7 +223,20 @@ static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); | |||
223 | 223 | ||
224 | static void sysrq_handle_showallcpus(int key, struct tty_struct *tty) | 224 | static void sysrq_handle_showallcpus(int key, struct tty_struct *tty) |
225 | { | 225 | { |
226 | trigger_all_cpu_backtrace(); | 226 | /* |
227 | * Fall back to the workqueue based printing if the | ||
228 | * backtrace printing did not succeed or the | ||
229 | * architecture has no support for it: | ||
230 | */ | ||
231 | if (!trigger_all_cpu_backtrace()) { | ||
232 | struct pt_regs *regs = get_irq_regs(); | ||
233 | |||
234 | if (regs) { | ||
235 | printk(KERN_INFO "CPU%d:\n", smp_processor_id()); | ||
236 | show_regs(regs); | ||
237 | } | ||
238 | schedule_work(&sysrq_showallcpus); | ||
239 | } | ||
227 | } | 240 | } |
228 | 241 | ||
229 | static struct sysrq_key_op sysrq_showallcpus_op = { | 242 | static struct sysrq_key_op sysrq_showallcpus_op = { |
diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 29af2d5df097..b752e807adde 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h | |||
@@ -28,8 +28,23 @@ static inline void acpi_nmi_disable(void) { } | |||
28 | static inline void acpi_nmi_enable(void) { } | 28 | static inline void acpi_nmi_enable(void) { } |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #ifndef trigger_all_cpu_backtrace | 31 | /* |
32 | #define trigger_all_cpu_backtrace() do { } while (0) | 32 | * Create trigger_all_cpu_backtrace() out of the arch-provided |
33 | * base function. Return whether such support was available, | ||
34 | * to allow calling code to fall back to some other mechanism: | ||
35 | */ | ||
36 | #ifdef arch_trigger_all_cpu_backtrace | ||
37 | static inline bool trigger_all_cpu_backtrace(void) | ||
38 | { | ||
39 | arch_trigger_all_cpu_backtrace(); | ||
40 | |||
41 | return true; | ||
42 | } | ||
43 | #else | ||
44 | static inline bool trigger_all_cpu_backtrace(void) | ||
45 | { | ||
46 | return false; | ||
47 | } | ||
33 | #endif | 48 | #endif |
34 | 49 | ||
35 | #endif | 50 | #endif |