| From ea6f121070cca941ce652bd7f1a7777e181e0395 Mon Sep 17 00:00:00 2001 |
| From: Ingo Molnar <mingo@elte.hu> |
| Date: Fri, 3 Jul 2009 08:30:19 -0500 |
| Subject: [PATCH] printk: rt support |
| |
| commit ba9d983171714db0483871cab172db4092f35699 in tip. |
| |
| 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/kernel/printk.c b/kernel/printk.c |
| index 45cf99a..2a07a18 100644 |
| --- a/kernel/printk.c |
| +++ b/kernel/printk.c |
| @@ -36,6 +36,7 @@ |
| #include <linux/ratelimit.h> |
| #include <linux/kmsg_dump.h> |
| #include <linux/syslog.h> |
| +#include <linux/semaphore.h> |
| |
| #include <asm/uaccess.h> |
| |
| @@ -423,7 +424,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); |
| } |
| @@ -539,6 +540,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) |
| @@ -677,7 +679,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! |
| @@ -692,7 +694,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(); |
| } |
| @@ -700,6 +702,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; |
| @@ -788,10 +791,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); |
| @@ -1054,15 +1055,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(); |
| } |
| @@ -1401,6 +1424,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.1.1 |
| |