X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fprintk.c;h=19a95561929478ffc99ac1552cf3ab645ec16bc1;hb=92445eaaadc1f03f5a177ecc957bda76bf2ba8d5;hp=8cc19431e74ba1d5c52095e7c0f97c56f6018734;hpb=2e1ca21d46aaef95101723fa402f39d3a95aba59;p=linux-2.6 diff --git a/kernel/printk.c b/kernel/printk.c index 8cc19431e7..19a9556192 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -67,6 +67,7 @@ EXPORT_SYMBOL(oops_in_progress); * driver system. */ static DECLARE_MUTEX(console_sem); +static DECLARE_MUTEX(secondary_console_sem); struct console *console_drivers; /* * This is used for debugging the mess that is the VT code by @@ -76,7 +77,7 @@ struct console *console_drivers; * path in the console code where we end up in places I want * locked without the console sempahore held */ -static int console_locked; +static int console_locked, console_suspended; /* * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars @@ -360,8 +361,7 @@ static void call_console_drivers(unsigned long start, unsigned long end) unsigned long cur_index, start_print; static int msg_level = -1; - if (((long)(start - end)) > 0) - BUG(); + BUG_ON(((long)(start - end)) > 0); cur_index = start; start_print = start; @@ -698,6 +698,23 @@ int __init add_preferred_console(char *name, int idx, char *options) return 0; } +/** + * suspend_console - suspend the console subsystem + * + * This disables printk() while we go into suspend states + */ +void suspend_console(void) +{ + acquire_console_sem(); + console_suspended = 1; +} + +void resume_console(void) +{ + console_suspended = 0; + release_console_sem(); +} + /** * acquire_console_sem - lock the console system for exclusive use. * @@ -708,8 +725,11 @@ int __init add_preferred_console(char *name, int idx, char *options) */ void acquire_console_sem(void) { - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); + if (console_suspended) { + down(&secondary_console_sem); + return; + } down(&console_sem); console_locked = 1; console_may_schedule = 1; @@ -752,6 +772,10 @@ void release_console_sem(void) unsigned long _con_start, _log_end; unsigned long wake_klogd = 0; + if (console_suspended) { + up(&secondary_console_sem); + return; + } for ( ; ; ) { spin_lock_irqsave(&logbuf_lock, flags); wake_klogd |= log_start - log_end;