From f8ae06b863293579bde1966c62b78b660dddf1ff Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:30:19 -0500 Subject: [PATCH] printk: rt support commit ba9d983171714db0483871cab172db4092f35699 in tip. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: Paul Gortmaker --- kernel/printk.c | 52 +++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 45 insertions(+), 7 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index 5b4ce9f..7293bd8 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -422,7 +423,7 @@ static void __call_console_drivers(unsigned start, unsigned end) for_each_console(con) { if ((con->flags & CON_ENABLED) && con->write && - (cpu_online(smp_processor_id()) || + (cpu_online(raw_smp_processor_id()) || (con->flags & CON_ANYTIME))) con->write(con, &LOG_BUF(start), end - start); } @@ -538,6 +539,7 @@ static void zap_locks(void) raw_spin_lock_init(&logbuf_lock); /* And make sure that we print immediately */ semaphore_init(&console_sem); + zap_rt_locks(); } #if defined(CONFIG_PRINTK_TIME) @@ -676,7 +678,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) preempt_disable(); /* This stops the holder of console_sem just where we want him */ raw_local_irq_save(flags); - this_cpu = smp_processor_id(); + this_cpu = raw_smp_processor_id(); /* * Ouch, printk recursed into itself! @@ -691,7 +693,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) */ if (!oops_in_progress) { recursion_bug = 1; - goto out_restore_irqs; + goto out; } zap_locks(); } @@ -699,6 +701,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) lockdep_off(); raw_spin_lock(&logbuf_lock); printk_cpu = this_cpu; + preempt_enable(); if (recursion_bug) { recursion_bug = 0; @@ -787,10 +790,8 @@ asmlinkage int vprintk(const char *fmt, va_list args) release_console_sem(); lockdep_on(); -out_restore_irqs: +out: raw_local_irq_restore(flags); - - preempt_enable(); return printed_len; } EXPORT_SYMBOL(printk); @@ -1053,15 +1054,37 @@ void release_console_sem(void) _con_start = con_start; _log_end = log_end; con_start = log_end; /* Flush */ + + /* + * on PREEMPT_RT, call console drivers with + * interrupts enabled (if printk was called + * with interrupts disabled): + */ +#ifdef CONFIG_PREEMPT_RT + raw_spin_unlock_irqrestore(&logbuf_lock, flags); +#else raw_spin_unlock(&logbuf_lock); stop_critical_timings(); /* don't trace print latency */ +#endif call_console_drivers(_con_start, _log_end); start_critical_timings(); +#ifndef CONFIG_PREEMPT_RT local_irq_restore(flags); +#endif } console_locked = 0; - up(&console_sem); raw_spin_unlock_irqrestore(&logbuf_lock, flags); + up(&console_sem); + + /* + * On PREEMPT_RT kernels __wake_up may sleep, so wake syslogd + * up only if we are in a preemptible section. We normally dont + * printk from non-preemptible sections so this is for the emergency + * case only. + */ +#ifdef CONFIG_PREEMPT_RT + if (!in_atomic() && !irqs_disabled()) +#endif if (wake_klogd) wake_up_klogd(); } @@ -1400,6 +1423,21 @@ bool printk_timed_ratelimit(unsigned long *caller_jiffies, } EXPORT_SYMBOL(printk_timed_ratelimit); +static DEFINE_RAW_SPINLOCK(warn_lock); + +void __WARN_ON(const char *func, const char *file, const int line) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&warn_lock, flags); + printk("%s/%d[CPU#%d]: BUG in %s at %s:%d\n", + current->comm, current->pid, raw_smp_processor_id(), + func, file, line); + dump_stack(); + raw_spin_unlock_irqrestore(&warn_lock, flags); +} +EXPORT_SYMBOL(__WARN_ON); + static DEFINE_SPINLOCK(dump_list_lock); static LIST_HEAD(dump_list); -- 1.7.0.4