[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:
parent
6031d9d9ad
commit
34c2a14fc2
|
@ -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()))
|
||||||
|
|
Loading…
Reference in New Issue