[POWERPC] Handle recursive oopses

Handle recursive oopses, like on x86. We had a few cases recently where
we locked up in oops printing and didnt make it into crashdump.

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
anton@samba.org 2007-03-20 20:38:13 -05:00 committed by Paul Mackerras
parent 6031d9d9ad
commit 34c2a14fc2
1 changed files with 36 additions and 16 deletions

View File

@ -108,42 +108,62 @@ static void pmac_backlight_unblank(void)
static inline void pmac_backlight_unblank(void) { } static inline void pmac_backlight_unblank(void) { }
#endif #endif
static DEFINE_SPINLOCK(die_lock);
int die(const char *str, struct pt_regs *regs, long err) int 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(die.lock),
.lock_owner = -1,
.lock_owner_depth = 0
};
static int die_counter; static int die_counter;
unsigned long flags;
if (debugger(regs)) if (debugger(regs))
return 1; return 1;
oops_enter(); oops_enter();
console_verbose(); if (die.lock_owner != raw_smp_processor_id()) {
spin_lock_irq(&die_lock); console_verbose();
bust_spinlocks(1); spin_lock_irqsave(&die.lock, flags);
if (machine_is(powermac)) die.lock_owner = smp_processor_id();
pmac_backlight_unblank(); die.lock_owner_depth = 0;
bust_spinlocks(1);
if (machine_is(powermac))
pmac_backlight_unblank();
} else {
local_save_flags(flags);
}
printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); if (++die.lock_owner_depth < 3) {
printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
printk("PREEMPT "); printk("PREEMPT ");
#endif #endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
printk("SMP NR_CPUS=%d ", NR_CPUS); printk("SMP NR_CPUS=%d ", NR_CPUS);
#endif #endif
#ifdef CONFIG_DEBUG_PAGEALLOC #ifdef CONFIG_DEBUG_PAGEALLOC
printk("DEBUG_PAGEALLOC "); printk("DEBUG_PAGEALLOC ");
#endif #endif
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
printk("NUMA "); printk("NUMA ");
#endif #endif
printk("%s\n", ppc_md.name ? "" : ppc_md.name); printk("%s\n", ppc_md.name ? "" : ppc_md.name);
print_modules();
show_regs(regs);
} else {
printk("Recursive die() failure, output suppressed\n");
}
print_modules();
show_regs(regs);
bust_spinlocks(0); bust_spinlocks(0);
spin_unlock_irq(&die_lock); die.lock_owner = -1;
spin_unlock_irqrestore(&die.lock, flags);
if (kexec_should_crash(current) || if (kexec_should_crash(current) ||
kexec_sr_activated(smp_processor_id())) kexec_sr_activated(smp_processor_id()))