Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=34c2a14fc20e4ab878fbf87e5f7fe1cff6afb3d4
Commit:     34c2a14fc20e4ab878fbf87e5f7fe1cff6afb3d4
Parent:     6031d9d9ad905b514bf45572bd1877fe6b5145ab
Author:     [EMAIL PROTECTED] <[EMAIL PROTECTED]>
AuthorDate: Tue Mar 20 20:38:13 2007 -0500
Committer:  Paul Mackerras <[EMAIL PROTECTED]>
CommitDate: Mon Mar 26 12:34:30 2007 +1000

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
 arch/powerpc/kernel/traps.c |   52 +++++++++++++++++++++++++++++-------------
 1 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6297da7..55d221f 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -108,42 +108,62 @@ static void pmac_backlight_unblank(void)
 static inline void pmac_backlight_unblank(void) { }
 #endif
 
-static DEFINE_SPINLOCK(die_lock);
-
 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;
+       unsigned long flags;
 
        if (debugger(regs))
                return 1;
 
        oops_enter();
 
-       console_verbose();
-       spin_lock_irq(&die_lock);
-       bust_spinlocks(1);
-       if (machine_is(powermac))
-               pmac_backlight_unblank();
+       if (die.lock_owner != raw_smp_processor_id()) {
+               console_verbose();
+               spin_lock_irqsave(&die.lock, flags);
+               die.lock_owner = smp_processor_id();
+               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
-       printk("PREEMPT ");
+               printk("PREEMPT ");
 #endif
 #ifdef CONFIG_SMP
-       printk("SMP NR_CPUS=%d ", NR_CPUS);
+               printk("SMP NR_CPUS=%d ", NR_CPUS);
 #endif
 #ifdef CONFIG_DEBUG_PAGEALLOC
-       printk("DEBUG_PAGEALLOC ");
+               printk("DEBUG_PAGEALLOC ");
 #endif
 #ifdef CONFIG_NUMA
-       printk("NUMA ");
+               printk("NUMA ");
 #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);
-       spin_unlock_irq(&die_lock);
+       die.lock_owner = -1;
+       spin_unlock_irqrestore(&die.lock, flags);
 
        if (kexec_should_crash(current) ||
                kexec_sr_activated(smp_processor_id()))
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to