summaryrefslogtreecommitdiffstats
path: root/printk-might-sleep-workaround.patch
blob: 2019d657a222c077a10f21297af2816ef84308d0 (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 0d825c8966569e2f2ec79a91a3203380b76e74e1 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Fri, 3 Jul 2009 08:44:02 -0500
Subject: [PATCH] printk: might sleep workaround

commit ee7503ec41dd08a6456e70ac3a6df74e539762df in tip.

PREEMPT_RT suffers from the on going problem of running
printk in atomic operations.  It is very advantageous to do so
but with PREEMPT_RT making spin_locks sleep, it can also be
devastating.

This patch does not solve the problem of printk sleeping in
an atomic operation. This patch just makes printk not report
that it is. Of course if printk does report that it's sleeping
in an atomic operation, then that printing of the report will
also print a report, and you go into recursive hell.

We need to really sit down and solve the real issue here.

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>
---
 include/linux/sched.h |   13 +++++++++++++
 kernel/printk.c       |    5 ++++-
 kernel/rtmutex.c      |    4 +++-
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 87565f8..6b6a43f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1575,11 +1575,24 @@ struct task_struct {
 		unsigned long memsw_bytes; /* uncharged mem+swap usage */
 	} memcg_batch;
 #endif
+#ifdef CONFIG_PREEMPT_RT
+	/*
+	 * Temporary hack, until we find a solution to
+	 * handle printk in atomic operations.
+	 */
+	int in_printk;
+#endif
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
 #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
 
+#ifdef CONFIG_PREEMPT_RT
+# define set_printk_might_sleep(x) do { current->in_printk = x; } while(0)
+#else
+# define set_printk_might_sleep(x) do { } while(0)
+#endif
+
 /*
  * Priority of a process goes from 0..MAX_PRIO-1, valid RT
  * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
diff --git a/kernel/printk.c b/kernel/printk.c
index 7293bd8..d27c203 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -424,8 +424,11 @@ 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)))
+				 (con->flags & CON_ANYTIME))) {
+			set_printk_might_sleep(1);
 			con->write(con, &LOG_BUF(start), end - start);
+			set_printk_might_sleep(0);
+		}
 	}
 }
 
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index 900f11c..dfbae19 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -678,7 +678,9 @@ static inline void
 rt_spin_lock_fastlock(struct rt_mutex *lock,
 		void  (*slowfn)(struct rt_mutex *lock))
 {
-	might_sleep();
+	/* Temporary HACK! */
+	if (!current->in_printk)
+		might_sleep();
 
 	if (likely(rt_mutex_cmpxchg(lock, NULL, current)))
 		rt_mutex_deadlock_account_lock(lock, current);
-- 
1.7.0.4