summaryrefslogtreecommitdiffstats
path: root/printk-in_atomic-fix.patch
blob: 33867a83629aa2576bc365c918487346c9d05ae4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
From 0d42bd69b4dfd305bf7753130d032166d2e5e2b4 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>
---
 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