| From d66b51582f975cab5a77f81a3f062356e5783e94 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> |
| |
| diff --git a/include/linux/sched.h b/include/linux/sched.h |
| index 1552624..5ceabb5 100644 |
| --- a/include/linux/sched.h |
| +++ b/include/linux/sched.h |
| @@ -1636,11 +1636,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 6c97e02..34adc5f 100644 |
| --- a/kernel/printk.c |
| +++ b/kernel/printk.c |
| @@ -431,8 +431,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.1.1 |
| |