| Subject: printk: Make rt aware |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Wed, 19 Sep 2012 14:50:37 +0200 |
| |
| Drop the lock before calling the console driver and do not disable |
| interrupts while printing to a serial console. |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| --- |
| kernel/printk/printk.c | 27 +++++++++++++++++++++++---- |
| 1 file changed, 23 insertions(+), 4 deletions(-) |
| |
| --- a/kernel/printk/printk.c |
| +++ b/kernel/printk/printk.c |
| @@ -1502,6 +1502,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; |
| @@ -1517,6 +1518,7 @@ static void call_console_drivers(int lev |
| else |
| con->write(con, text, len); |
| } |
| + migrate_enable(); |
| } |
| |
| /* |
| @@ -1577,6 +1579,15 @@ static inline int can_use_console(unsign |
| static int console_trylock_for_printk(void) |
| { |
| unsigned int cpu = smp_processor_id(); |
| +#ifdef CONFIG_PREEMPT_RT_FULL |
| + int lock = !early_boot_irqs_disabled && (preempt_count() == 0) && |
| + !irqs_disabled(); |
| +#else |
| + int lock = 1; |
| +#endif |
| + |
| + if (!lock) |
| + return 0; |
| |
| if (!console_trylock()) |
| return 0; |
| @@ -1879,8 +1890,7 @@ asmlinkage int vprintk_emit(int facility |
| * console_sem which would prevent anyone from printing to |
| * console |
| */ |
| - preempt_disable(); |
| - |
| + migrate_disable(); |
| /* |
| * Try to acquire and then immediately release the console |
| * semaphore. The release will print out buffers and wake up |
| @@ -1888,7 +1898,7 @@ asmlinkage int vprintk_emit(int facility |
| */ |
| if (console_trylock_for_printk()) |
| console_unlock(); |
| - preempt_enable(); |
| + migrate_enable(); |
| lockdep_on(); |
| } |
| |
| @@ -2248,11 +2258,16 @@ static void console_cont_flush(char *tex |
| goto out; |
| |
| len = cont_print_text(text, size); |
| +#ifdef CONFIG_PREEMPT_RT_FULL |
| + raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| + call_console_drivers(cont.level, NULL, 0, text, len); |
| +#else |
| raw_spin_unlock(&logbuf_lock); |
| stop_critical_timings(); |
| call_console_drivers(cont.level, NULL, 0, text, len); |
| start_critical_timings(); |
| local_irq_restore(flags); |
| +#endif |
| return; |
| out: |
| raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| @@ -2362,13 +2377,17 @@ void console_unlock(void) |
| console_idx = log_next(console_idx); |
| console_seq++; |
| console_prev = msg->flags; |
| +#ifdef CONFIG_PREEMPT_RT_FULL |
| + raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| + call_console_drivers(level, ext_text, ext_len, text, len); |
| +#else |
| raw_spin_unlock(&logbuf_lock); |
| |
| stop_critical_timings(); /* don't trace print latency */ |
| call_console_drivers(level, ext_text, ext_len, text, len); |
| start_critical_timings(); |
| local_irq_restore(flags); |
| - |
| +#endif |
| if (do_cond_resched) |
| cond_resched(); |
| } |