Under certain, rather special, circumstances its impossible to wake up klogd, for these provide: printk_nowakeup(). These circumstances include: holding rq->lock and or xtime lock. Signed-off-by: Peter Zijlstra --- include/linux/kernel.h | 4 +++- kernel/printk.c | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 6 deletions(-) Index: linux-2.6-2/include/linux/kernel.h =================================================================== --- linux-2.6-2.orig/include/linux/kernel.h +++ linux-2.6-2/include/linux/kernel.h @@ -179,7 +179,9 @@ extern struct pid *session_of_pgrp(struc #ifdef CONFIG_PRINTK asmlinkage int vprintk(const char *fmt, va_list args) __attribute__ ((format (printf, 1, 0))); -asmlinkage int printk(const char * fmt, ...) +asmlinkage int printk(const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))) __cold; +asmlinkage int printk_nowakeup(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))) __cold; extern int log_buf_get_len(void); extern int log_buf_read(int idx); Index: linux-2.6-2/kernel/printk.c =================================================================== --- linux-2.6-2.orig/kernel/printk.c +++ linux-2.6-2/kernel/printk.c @@ -612,6 +612,7 @@ asmlinkage int printk(const char *fmt, . return r; } +EXPORT_SYMBOL(printk); /* cpu currently holding logbuf_lock */ static volatile unsigned int printk_cpu = UINT_MAX; @@ -621,7 +622,9 @@ static int recursion_bug; static int log_level_unknown = 1; static char printk_buf[1024]; -asmlinkage int vprintk(const char *fmt, va_list args) +static int __release_console_sem(void); + +static int __vprintk(int wakeup, const char *fmt, va_list args) { unsigned long flags; int printed_len = 0; @@ -740,7 +743,8 @@ asmlinkage int vprintk(const char *fmt, */ if (cpu_online(smp_processor_id()) || have_callable_console()) { console_may_schedule = 0; - release_console_sem(); + if (__release_console_sem() && wakeup) + wake_up_klogd(); } else { /* Release by hand to avoid flushing the buffer. */ console_locked = 0; @@ -764,7 +768,23 @@ out_restore_irqs: preempt_enable(); return printed_len; } -EXPORT_SYMBOL(printk); + +asmlinkage int printk_nowakeup(const char *fmt, ...) +{ + va_list args; + int r; + + va_start(args, fmt); + r = __vprintk(0, fmt, args); + va_end(args); + + return r; +} + +asmlinkage int vprintk(const char *fmt, va_list args) +{ + return __vprintk(1, fmt, args); +} EXPORT_SYMBOL(vprintk); #else @@ -964,7 +984,7 @@ void wake_up_klogd(void) * * release_console_sem() may be called from any context. */ -void release_console_sem(void) +static int __release_console_sem(void) { unsigned long flags; unsigned _con_start, _log_end; @@ -994,7 +1014,13 @@ void release_console_sem(void) console_locked = 0; up(&console_sem); spin_unlock_irqrestore(&logbuf_lock, flags); - if (wake_klogd) + + return wake_klogd; +} + +void release_console_sem(void) +{ + if (__release_console_sem()) wake_up_klogd(); } EXPORT_SYMBOL(release_console_sem); -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/