From: Ingo Molnar printk currently does if (oops_in_progres) bust_printk_locks(); which means that once we oops, the printk locking is 100% ineffective and multiple CPUs make an unreadable mess on a serial console. It's a significant development hassle. Fix that up by only popping locks once per ten seconds. --- 25-akpm/kernel/printk.c | 28 ++++++++++++++++++++++------ 1 files changed, 22 insertions(+), 6 deletions(-) diff -puN kernel/printk.c~mangled-printk-oops-output-fix kernel/printk.c --- 25/kernel/printk.c~mangled-printk-oops-output-fix Thu May 20 15:59:39 2004 +++ 25-akpm/kernel/printk.c Thu May 20 15:59:39 2004 @@ -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); _