blob: 12a58c75a2ad32ee968a4f4fa5a8db2331383fe2 [file] [log] [blame]
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