diff options
Diffstat (limited to 'arch/x86/kernel/apic/nmi.c')
| -rw-r--r-- | arch/x86/kernel/apic/nmi.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index b3025b43b63a..db7220220d09 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c | |||
| @@ -39,7 +39,7 @@ | |||
| 39 | int unknown_nmi_panic; | 39 | int unknown_nmi_panic; |
| 40 | int nmi_watchdog_enabled; | 40 | int nmi_watchdog_enabled; |
| 41 | 41 | ||
| 42 | static cpumask_var_t backtrace_mask; | 42 | static cpumask_t backtrace_mask __read_mostly; |
| 43 | 43 | ||
| 44 | /* nmi_active: | 44 | /* nmi_active: |
| 45 | * >0: the lapic NMI watchdog is active, but can be disabled | 45 | * >0: the lapic NMI watchdog is active, but can be disabled |
| @@ -138,7 +138,6 @@ int __init check_nmi_watchdog(void) | |||
| 138 | if (!prev_nmi_count) | 138 | if (!prev_nmi_count) |
| 139 | goto error; | 139 | goto error; |
| 140 | 140 | ||
| 141 | alloc_cpumask_var(&backtrace_mask, GFP_KERNEL|__GFP_ZERO); | ||
| 142 | printk(KERN_INFO "Testing NMI watchdog ... "); | 141 | printk(KERN_INFO "Testing NMI watchdog ... "); |
| 143 | 142 | ||
| 144 | #ifdef CONFIG_SMP | 143 | #ifdef CONFIG_SMP |
| @@ -415,14 +414,17 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) | |||
| 415 | } | 414 | } |
| 416 | 415 | ||
| 417 | /* We can be called before check_nmi_watchdog, hence NULL check. */ | 416 | /* We can be called before check_nmi_watchdog, hence NULL check. */ |
| 418 | if (backtrace_mask != NULL && cpumask_test_cpu(cpu, backtrace_mask)) { | 417 | if (cpumask_test_cpu(cpu, &backtrace_mask)) { |
| 419 | static DEFINE_SPINLOCK(lock); /* Serialise the printks */ | 418 | static DEFINE_SPINLOCK(lock); /* Serialise the printks */ |
| 420 | 419 | ||
| 421 | spin_lock(&lock); | 420 | spin_lock(&lock); |
| 422 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); | 421 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); |
| 422 | show_regs(regs); | ||
| 423 | dump_stack(); | 423 | dump_stack(); |
| 424 | spin_unlock(&lock); | 424 | spin_unlock(&lock); |
| 425 | cpumask_clear_cpu(cpu, backtrace_mask); | 425 | cpumask_clear_cpu(cpu, &backtrace_mask); |
| 426 | |||
| 427 | rc = 1; | ||
| 426 | } | 428 | } |
| 427 | 429 | ||
| 428 | /* Could check oops_in_progress here too, but it's safer not to */ | 430 | /* Could check oops_in_progress here too, but it's safer not to */ |
| @@ -552,14 +554,18 @@ int do_nmi_callback(struct pt_regs *regs, int cpu) | |||
| 552 | return 0; | 554 | return 0; |
| 553 | } | 555 | } |
| 554 | 556 | ||
| 555 | void __trigger_all_cpu_backtrace(void) | 557 | void arch_trigger_all_cpu_backtrace(void) |
| 556 | { | 558 | { |
| 557 | int i; | 559 | int i; |
| 558 | 560 | ||
| 559 | cpumask_copy(backtrace_mask, cpu_online_mask); | 561 | cpumask_copy(&backtrace_mask, cpu_online_mask); |
| 562 | |||
| 563 | printk(KERN_INFO "sending NMI to all CPUs:\n"); | ||
| 564 | apic->send_IPI_all(NMI_VECTOR); | ||
| 565 | |||
| 560 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ | 566 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ |
| 561 | for (i = 0; i < 10 * 1000; i++) { | 567 | for (i = 0; i < 10 * 1000; i++) { |
| 562 | if (cpumask_empty(backtrace_mask)) | 568 | if (cpumask_empty(&backtrace_mask)) |
| 563 | break; | 569 | break; |
| 564 | mdelay(1); | 570 | mdelay(1); |
| 565 | } | 571 | } |
