Re: overlaping printk

From: Ingo Molnar
Date: Thu May 20 2004 - 13:57:05 EST



* Andy Isaacson <adi@xxxxxxxxxxxxx> wrote:

> It looks like this will cause problems if the user experiences an oops
> during boot, runs for a few hours, and then has another oops. Won't
> the second oops fail to break the lock, and end up just deadlocking?

i've attached a new patch that does what Andi suggested too -
timestamping of the oopses. This way we will zap no sooner than 10
seconds after the first oops.

Ingo
--- linux/kernel/printk.c.orig
+++ linux/kernel/printk.c
@@ -55,6 +55,9 @@ EXPORT_SYMBOL(console_printk);

int oops_in_progress;

+/* zap spinlocks only once: */
+unsigned long oops_timestamp;
+
/*
* console_sem protects the console_drivers list, and also
* provides serialisation for access to the entire console
@@ -472,6 +475,23 @@ static void emit_log_char(char c)
}

/*
+ * 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 inline void zap_locks(void)
+{
+ if (!time_after(jiffies, oops_timestamp + 10*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.
*
* We try to grab the console_sem. If we succeed, it's easy - we log the output and
@@ -493,12 +513,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);