diff options
author | Andrew Morton <akpm@osdl.org> | 2004-05-24 18:36:46 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-05-24 18:36:46 -0700 |
commit | c570d66770cfaf169ba91e43f6243ddbac8efd73 (patch) | |
tree | 9afb22d625740c1ca0eff221e3db0268d41c4f32 /kernel | |
parent | ed8d9961f3c411b5b3ab2a673e66bfc01827a46b (diff) | |
download | history-c570d66770cfaf169ba91e43f6243ddbac8efd73.tar.gz |
[PATCH] Fix the mangled-oops-output-on-SMP problem
From: Ingo Molnar <mingo@elte.hu>
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.
akpm@osdl.org did:
- Bump the timeout to 30 seconds - 9600 baud is slow.
- Handle jiffy wraps: change the logic so that we only skip the lockbust
if the current time is within 30 seconds of the previous lockbusting
attempt.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/printk.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 3b74688184a8d4..9e34ce41beb6de 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -472,6 +472,27 @@ 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 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. * * We try to grab the console_sem. If we succeed, it's easy - we log the output and @@ -493,12 +514,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); |