From: Keith Owens Make i386 die() more resilient against recursive errors, almost a cut and paste of the ia64 die() routine. Much of the patch is indentation changes. Mainly to make it easier to add crash, lcrash, kmsgdump or other RAS patches. They are invoked from die() and if they crash themselves, we have to avoid recursive loops in die(). Signed-off-by: Keith Owens Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/kernel/traps.c | 53 +++++++++++++++++++++++++-------------- 1 files changed, 35 insertions(+), 18 deletions(-) diff -puN arch/i386/kernel/traps.c~make-i386-die-more-resilient-against-recursive-errors arch/i386/kernel/traps.c --- 25/arch/i386/kernel/traps.c~make-i386-die-more-resilient-against-recursive-errors 2004-07-26 17:10:26.410782080 -0700 +++ 25-akpm/arch/i386/kernel/traps.c 2004-07-26 17:10:26.415781320 -0700 @@ -292,35 +292,52 @@ bug: printk("Kernel BUG\n"); } -spinlock_t die_lock = SPIN_LOCK_UNLOCKED; - void die(const char * str, struct pt_regs * regs, long err) { + static struct { + spinlock_t lock; + u32 lock_owner; + int lock_owner_depth; + } die = { + .lock = SPIN_LOCK_UNLOCKED, + .lock_owner = -1, + .lock_owner_depth = 0 + }; static int die_counter; - int nl = 0; - console_verbose(); - spin_lock_irq(&die_lock); - bust_spinlocks(1); - handle_BUG(regs); - printk(KERN_ALERT "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); + if (die.lock_owner != smp_processor_id()) { + console_verbose(); + spin_lock_irq(&die.lock); + die.lock_owner = smp_processor_id(); + die.lock_owner_depth = 0; + bust_spinlocks(1); + } + + if (++die.lock_owner_depth < 3) { + int nl = 0; + handle_BUG(regs); + printk(KERN_ALERT "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); #ifdef CONFIG_PREEMPT - printk("PREEMPT "); - nl = 1; + printk("PREEMPT "); + nl = 1; #endif #ifdef CONFIG_SMP - printk("SMP "); - nl = 1; + printk("SMP "); + nl = 1; #endif #ifdef CONFIG_DEBUG_PAGEALLOC - printk("DEBUG_PAGEALLOC"); - nl = 1; + printk("DEBUG_PAGEALLOC"); + nl = 1; #endif - if (nl) - printk("\n"); - show_registers(regs); + if (nl) + printk("\n"); + show_registers(regs); + } else + printk(KERN_ERR "Recursive die() failure, output suppressed\n"); + bust_spinlocks(0); - spin_unlock_irq(&die_lock); + die.lock_owner = -1; + spin_unlock_irq(&die.lock); if (in_interrupt()) panic("Fatal exception in interrupt"); _