From 0d42bd69b4dfd305bf7753130d032166d2e5e2b4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:44:16 -0500 Subject: [PATCH] printk: in_atomic fix commit 96cd28c9235962fa85b9ccb43cdb129152a2c38b in tip. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: Paul Gortmaker --- arch/x86/kernel/early_printk.c | 4 ++-- drivers/char/vt.c | 2 +- include/linux/console.h | 11 +++++++++++ kernel/printk.c | 5 +++-- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 3c5a9e0..02aaf8f 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -59,7 +59,7 @@ static void early_vga_write(struct console *con, const char *str, unsigned n) static struct console early_vga_console = { .name = "earlyvga", .write = early_vga_write, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_ATOMIC, .index = -1, }; @@ -156,7 +156,7 @@ static __init void early_serial_init(char *s) static struct console early_serial_console = { .name = "earlyser", .write = early_serial_write, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_ATOMIC, .index = -1, }; diff --git a/drivers/char/vt.c b/drivers/char/vt.c index bd1d116..e87aed9 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -2571,7 +2571,7 @@ static struct console vt_console_driver = { .write = vt_console_print, .device = vt_console_device, .unblank = unblank_screen, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_ATOMIC, .index = -1, }; #endif diff --git a/include/linux/console.h b/include/linux/console.h index 7c2c9ae..81651ad 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -93,6 +93,17 @@ void give_up_console(const struct consw *sw); #define CON_BOOT (8) #define CON_ANYTIME (16) /* Safe to call when cpu is offline */ #define CON_BRL (32) /* Used for a braille device */ +#define CON_ATOMIC (64) /* Safe to call in PREEMPT_RT atomic */ + +#ifdef CONFIG_PREEMPT_RT +# define console_atomic_safe(con) \ + (((con)->flags & CON_ATOMIC) || \ + (!in_atomic() && !irqs_disabled()) || \ + (system_state != SYSTEM_RUNNING) || \ + oops_in_progress) +#else +# define console_atomic_safe(con) (1) +#endif struct console { char name[16]; diff --git a/kernel/printk.c b/kernel/printk.c index d27c203..de0f29c 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -423,8 +423,9 @@ static void __call_console_drivers(unsigned start, unsigned end) for_each_console(con) { if ((con->flags & CON_ENABLED) && con->write && - (cpu_online(raw_smp_processor_id()) || - (con->flags & CON_ANYTIME))) { + console_atomic_safe(con) && + (cpu_online(raw_smp_processor_id()) || + (con->flags & CON_ANYTIME))) { set_printk_might_sleep(1); con->write(con, &LOG_BUF(start), end - start); set_printk_might_sleep(0); -- 1.7.0.4