fix sysrq+l when nmi_watchdog disabled
PATCH 1/1 fix sysrq+l when nmi_watchdog disabled
From: Hiroshi Shimamoto <[email protected]>
In nmi_show_all_regs(), set nmi_show_regs for all cpus but NMI never come to itself when nmi_watchdog is disabled. It means the kernel hangs up when sysrq+l is issued.
Call irq_show_regs_callback() itself before calling smp_send_nmi_allbutself().
---
Steven, this is a fix for what you pointed.
http://lkml.org/lkml/2008/4/28/455
arch/x86/kernel/nmi_32.c | 51 ++++++++++++++++++++++++++++------------------ arch/x86/kernel/nmi_64.c | 49 ++++++++++++++++++++++++++++--------------- 2 files changed, 63 insertions(+), 37 deletions(-)
arch/x86/kernel/nmi_32.c +31 -20
@@ -325,21 +325,49 @@ extern void die_nmi(struct pt_regs *, const char *msg);int nmi_show_regs[NR_CPUS ]; +static DEFINE_RAW_SPINLOCK (nmi_print_lock); + +notrace int irq_show_regs_callback(int cpu, struct pt_regs *regs) +{ +if (!nmi_show_regs[cpu]) +return 0 ; + +spin_lock (&nmi_print_lock); +printk (KERN_WARNING "NMI show regs on CPU#%d:\n" , cpu); +printk (KERN_WARNING "apic_timer_irqs: %d\n" , +per_cpu (irq_stat, cpu).apic_timer_irqs); +show_regs (regs); +spin_unlock (&nmi_print_lock); + nmi_show_regs[cpu] =0 ; +return 1 ; +} +void nmi_show_all_regs (void ) { -int i; +struct pt_regs *regs; +int i, cpu;if (system_state ==SYSTEM_BOOTING )return ; -printk (KERN_WARNING "nmi_show_all_regs(): start on CPU#%d.\n" , -raw_smp_processor_id ()); +preempt_disable (); + + regs =get_irq_regs (); + cpu =smp_processor_id (); + +printk (KERN_WARNING "nmi_show_all_regs(): start on CPU#%d.\n" , cpu);dump_stack ();for_each_online_cpu (i) nmi_show_regs[i] =1 ; +if (regs) +irq_show_regs_callback (cpu, regs); +else + nmi_show_regs[cpu] =0 ; +smp_send_nmi_allbutself (); +preempt_enable ();for_each_online_cpu (i) {while (nmi_show_regs[i] ==1 )
@@ -347,23 +375,6 @@ void nmi_show_all_regs(void) } } -static DEFINE_RAW_SPINLOCK (nmi_print_lock); - -notrace int irq_show_regs_callback(int cpu, struct pt_regs *regs) -{ -if (!nmi_show_regs[cpu]) -return 0 ; - -spin_lock (&nmi_print_lock); -printk (KERN_WARNING "NMI show regs on CPU#%d:\n" , cpu); -printk (KERN_WARNING "apic_timer_irqs: %d\n" , -per_cpu (irq_stat, cpu).apic_timer_irqs); -show_regs (regs); -spin_unlock (&nmi_print_lock); - nmi_show_regs[cpu] =0 ; -return 1 ; -} -__kprobes int nmi_watchdog_tick (struct pt_regs * regs,unsigned reason) {
arch/x86/kernel/nmi_64.c +32 -16
67 lines not on this page · raw message
Quoted 7 lines · Hiroshi Shimamoto
From: Hiroshi Shimamoto <[email protected]>
In
nmi_show_all_regs(), setnmi_show_regsfor all cpus but NMI never come to itself whennmi_watchdogis disabled. It means the kernel hangs up when sysrq+l is issued.Call
irq_show_regs_callback()itself before callingsmp_send_nmi_allbutself().
Thanks,
I had a patch to do this fix but it got lost. I'll add yours.
-- Steve
Quoted 3 lines
Signed-off-by Hiroshi Shimamoto <[email protected]>---