| Subject: printk-rt-aware.patch |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Wed, 19 Sep 2012 14:50:37 +0200 |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| --- |
| kernel/printk.c | 33 +++++++++++++++++++++++++++++---- |
| 1 file changed, 29 insertions(+), 4 deletions(-) |
| |
| --- a/kernel/printk.c |
| +++ b/kernel/printk.c |
| @@ -1315,6 +1315,7 @@ static void call_console_drivers(int lev |
| if (!console_drivers) |
| return; |
| |
| + migrate_disable(); |
| for_each_console(con) { |
| if (exclusive_console && con != exclusive_console) |
| continue; |
| @@ -1327,6 +1328,7 @@ static void call_console_drivers(int lev |
| continue; |
| con->write(con, text, len); |
| } |
| + migrate_enable(); |
| } |
| |
| /* |
| @@ -1386,12 +1388,18 @@ static inline int can_use_console(unsign |
| * interrupts disabled. It should return with 'lockbuf_lock' |
| * released but interrupts still disabled. |
| */ |
| -static int console_trylock_for_printk(unsigned int cpu) |
| +static int console_trylock_for_printk(unsigned int cpu, unsigned long flags) |
| __releases(&logbuf_lock) |
| { |
| int retval = 0, wake = 0; |
| +#ifdef CONFIG_PREEMPT_RT_FULL |
| + int lock = !early_boot_irqs_disabled && !irqs_disabled_flags(flags) && |
| + (preempt_count() <= 1); |
| +#else |
| + int lock = 1; |
| +#endif |
| |
| - if (console_trylock()) { |
| + if (lock && console_trylock()) { |
| retval = 1; |
| |
| /* |
| @@ -1670,8 +1678,15 @@ asmlinkage int vprintk_emit(int facility |
| * The console_trylock_for_printk() function will release 'logbuf_lock' |
| * regardless of whether it actually gets the console semaphore or not. |
| */ |
| - if (console_trylock_for_printk(this_cpu)) |
| + if (console_trylock_for_printk(this_cpu, flags)) { |
| +#ifndef CONFIG_PREEMPT_RT_FULL |
| + console_unlock(); |
| +#else |
| + raw_local_irq_restore(flags); |
| console_unlock(); |
| + raw_local_irq_save(flags); |
| +#endif |
| + } |
| |
| lockdep_on(); |
| out_restore_irqs: |
| @@ -2060,11 +2075,16 @@ static void console_cont_flush(char *tex |
| goto out; |
| |
| len = cont_print_text(text, size); |
| +#ifndef CONFIG_PREEMPT_RT_FULL |
| raw_spin_unlock(&logbuf_lock); |
| stop_critical_timings(); |
| call_console_drivers(cont.level, text, len); |
| start_critical_timings(); |
| local_irq_restore(flags); |
| +#else |
| + raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| + call_console_drivers(cont.level, text, len); |
| +#endif |
| return; |
| out: |
| raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| @@ -2147,12 +2167,17 @@ skip: |
| console_idx = log_next(console_idx); |
| console_seq++; |
| console_prev = msg->flags; |
| - raw_spin_unlock(&logbuf_lock); |
| |
| +#ifndef CONFIG_PREEMPT_RT_FULL |
| + raw_spin_unlock(&logbuf_lock); |
| stop_critical_timings(); /* don't trace print latency */ |
| call_console_drivers(level, text, len); |
| start_critical_timings(); |
| local_irq_restore(flags); |
| +#else |
| + raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| + call_console_drivers(level, text, len); |
| +#endif |
| } |
| console_locked = 0; |
| |