| From 3f5cba66e7d077e07897a1e490b4d0b6200a0c74 Mon Sep 17 00:00:00 2001 |
| From: Ingo Molnar <mingo@elte.hu> |
| Date: Fri, 3 Jul 2009 08:44:16 -0500 |
| Subject: [PATCH] printk: in_atomic fix |
| |
| commit 96cd28c9235962fa85b9ccb43cdb129152a2c38b in tip. |
| |
| Signed-off-by: Ingo Molnar <mingo@elte.hu> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| 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 50faa1f..c52ba9b 100644 |
| --- a/drivers/char/vt.c |
| +++ b/drivers/char/vt.c |
| @@ -2575,7 +2575,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 34adc5f..539b8ce 100644 |
| --- a/kernel/printk.c |
| +++ b/kernel/printk.c |
| @@ -430,8 +430,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.1.1 |
| |