patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / kernel / printk.c
index bb5ac82..3bf268b 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/smp.h>
 #include <linux/security.h>
 #include <linux/bootmem.h>
+#include <linux/vs_base.h>
 
 #include <asm/uaccess.h>
 
@@ -474,6 +475,27 @@ static void emit_log_char(char c)
                logged_chars++;
 }
 
+/*
+ * Zap console related locks when oopsing. Only zap at most once
+ * every 10 seconds, to leave time for slow consoles to print a
+ * full oops.
+ */
+static void zap_locks(void)
+{
+       static unsigned long oops_timestamp;
+
+       if (time_after_eq(jiffies, oops_timestamp) &&
+                       !time_after(jiffies, oops_timestamp + 30*HZ))
+               return;
+
+       oops_timestamp = jiffies;
+
+       /* If a crash is occurring, make sure we can't deadlock */
+       spin_lock_init(&logbuf_lock);
+       /* And make sure that we print immediately */
+       init_MUTEX(&console_sem);
+}
+
 /*
  * This is printk.  It can be called from any context.  We want it to work.
  * 
@@ -496,12 +518,8 @@ asmlinkage int printk(const char *fmt, ...)
        static char printk_buf[1024];
        static int log_level_unknown = 1;
 
-       if (oops_in_progress) {
-               /* If a crash is occurring, make sure we can't deadlock */
-               spin_lock_init(&logbuf_lock);
-               /* And make sure that we print immediately */
-               init_MUTEX(&console_sem);
-       }
+       if (unlikely(oops_in_progress))
+               zap_locks();
 
        /* This stops the holder of console_sem just where we want him */
        spin_lock_irqsave(&logbuf_lock, flags);