summaryrefslogtreecommitdiffstats
path: root/printk-rt-support.patch
blob: ff581ac1dd5b8b457c6dec2d391ea7d34324ce3e (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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
From f8ae06b863293579bde1966c62b78b660dddf1ff Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Fri, 3 Jul 2009 08:30:19 -0500
Subject: [PATCH] printk: rt support

commit ba9d983171714db0483871cab172db4092f35699 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>
---
 kernel/printk.c |   52 +++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/kernel/printk.c b/kernel/printk.c
index 5b4ce9f..7293bd8 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -36,6 +36,7 @@
 #include <linux/ratelimit.h>
 #include <linux/kmsg_dump.h>
 #include <linux/syslog.h>
+#include <linux/semaphore.h>
 
 #include <asm/uaccess.h>
 
@@ -422,7 +423,7 @@ static void __call_console_drivers(unsigned start, unsigned end)
 
 	for_each_console(con) {
 		if ((con->flags & CON_ENABLED) && con->write &&
-				(cpu_online(smp_processor_id()) ||
+				(cpu_online(raw_smp_processor_id()) ||
 				(con->flags & CON_ANYTIME)))
 			con->write(con, &LOG_BUF(start), end - start);
 	}
@@ -538,6 +539,7 @@ static void zap_locks(void)
 	raw_spin_lock_init(&logbuf_lock);
 	/* And make sure that we print immediately */
 	semaphore_init(&console_sem);
+	zap_rt_locks();
 }
 
 #if defined(CONFIG_PRINTK_TIME)
@@ -676,7 +678,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 	preempt_disable();
 	/* This stops the holder of console_sem just where we want him */
 	raw_local_irq_save(flags);
-	this_cpu = smp_processor_id();
+	this_cpu = raw_smp_processor_id();
 
 	/*
 	 * Ouch, printk recursed into itself!
@@ -691,7 +693,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 		 */
 		if (!oops_in_progress) {
 			recursion_bug = 1;
-			goto out_restore_irqs;
+			goto out;
 		}
 		zap_locks();
 	}
@@ -699,6 +701,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 	lockdep_off();
 	raw_spin_lock(&logbuf_lock);
 	printk_cpu = this_cpu;
+	preempt_enable();
 
 	if (recursion_bug) {
 		recursion_bug = 0;
@@ -787,10 +790,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 		release_console_sem();
 
 	lockdep_on();
-out_restore_irqs:
+out:
 	raw_local_irq_restore(flags);
-
-	preempt_enable();
 	return printed_len;
 }
 EXPORT_SYMBOL(printk);
@@ -1053,15 +1054,37 @@ void release_console_sem(void)
 		_con_start = con_start;
 		_log_end = log_end;
 		con_start = log_end;		/* Flush */
+
+		/*
+		 * on PREEMPT_RT, call console drivers with
+		 * interrupts enabled (if printk was called
+		 * with interrupts disabled):
+		 */
+#ifdef CONFIG_PREEMPT_RT
+		raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+#else
 		raw_spin_unlock(&logbuf_lock);
 		stop_critical_timings();	/* don't trace print latency */
+#endif
 		call_console_drivers(_con_start, _log_end);
 		start_critical_timings();
+#ifndef CONFIG_PREEMPT_RT
 		local_irq_restore(flags);
+#endif
 	}
 	console_locked = 0;
-	up(&console_sem);
 	raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+	up(&console_sem);
+
+	/*
+	 * On PREEMPT_RT kernels __wake_up may sleep, so wake syslogd
+	 * up only if we are in a preemptible section. We normally dont
+	 * printk from non-preemptible sections so this is for the emergency
+	 * case only.
+	 */
+#ifdef CONFIG_PREEMPT_RT
+	if (!in_atomic() && !irqs_disabled())
+#endif
 	if (wake_klogd)
 		wake_up_klogd();
 }
@@ -1400,6 +1423,21 @@ bool printk_timed_ratelimit(unsigned long *caller_jiffies,
 }
 EXPORT_SYMBOL(printk_timed_ratelimit);
 
+static DEFINE_RAW_SPINLOCK(warn_lock);
+
+void __WARN_ON(const char *func, const char *file, const int line)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&warn_lock, flags);
+	printk("%s/%d[CPU#%d]: BUG in %s at %s:%d\n",
+		current->comm, current->pid, raw_smp_processor_id(),
+		func, file, line);
+	dump_stack();
+	raw_spin_unlock_irqrestore(&warn_lock, flags);
+}
+EXPORT_SYMBOL(__WARN_ON);
+
 static DEFINE_SPINLOCK(dump_list_lock);
 static LIST_HEAD(dump_list);
 
-- 
1.7.0.4