blob: 3245a9f96b933e23db26369b63164b893fcd2065 [file] [log] [blame]
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