| 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 |
| @@ -1277,6 +1277,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; |
| @@ -1289,6 +1290,7 @@ static void call_console_drivers(int lev |
| continue; |
| con->write(con, text, len); |
| } |
| + migrate_enable(); |
| } |
| |
| /* |
| @@ -1348,12 +1350,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; |
| |
| /* |
| @@ -1688,8 +1696,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: |
| @@ -2043,11 +2058,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); |
| @@ -2130,12 +2150,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; |
| mutex_release(&console_lock_dep_map, 1, _RET_IP_); |