[PATCH 10/10] printk: Split console call from vprintk_emit()

From: Petr Mladek
Date: Mon May 25 2015 - 08:47:25 EST


vprintk_emit() is too long. Let's split the logic about when and how
to call the console into a separate function.

Well, it is not only about console but also about /dev/kmsg and syslog().
Hence the generic name vprintk_poke_loggers() seems to be more appropriate.

This patch just shuffles the code. There is no change in the functionality.

Signed-off-by: Petr Mladek <pmladek@xxxxxxx>
---
kernel/printk/printk.c | 72 ++++++++++++++++++++++++++++----------------------
1 file changed, 41 insertions(+), 31 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index c0b97653987a..fb4af49c2d4e 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1877,6 +1877,46 @@ static int vprintk_store_text(int facility, int level, enum log_flags lflags,
return printed_len;
}

+/*
+ * Try to get console, wake up logging services, and flush the last
+ * messages there.
+ */
+static void vprintk_poke_loggers(bool in_sched)
+{
+ /*
+ * If called from the scheduler or NMI context, we can not get console
+ * without a possible deadlock. In this case, we must deffer the task
+ * via IRQ work.
+ *
+ * The only exception are Oops messages from NMI context where all
+ * relevant locks have been forcefully dropped in
+ * try_logbuf_lock_in_nmi(). We have to try to get the console,
+ * otherwise the last messages would get lost.
+ */
+ if (in_sched || (in_nmi() && !oops_in_progress)) {
+ __this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT);
+ irq_work_queue(this_cpu_ptr(&wake_up_klogd_work));
+ } else {
+ lockdep_off();
+ /*
+ * Disable preemption to avoid being preempted while holding
+ * console_sem which would prevent anyone from printing to
+ * console
+ */
+ preempt_disable();
+
+ /*
+ * Try to acquire and then immediately release the console
+ * semaphore. The release will print out buffers and wake up
+ * /dev/kmsg and syslog() users.
+ */
+ if (console_trylock_for_printk())
+ console_unlock();
+ preempt_enable();
+ lockdep_on();
+ }
+}
+
asmlinkage int vprintk_emit(int facility, int level,
const char *dict, size_t dictlen,
const char *fmt, va_list args)
@@ -1952,37 +1992,7 @@ asmlinkage int vprintk_emit(int facility, int level,
lockdep_on();
local_irq_restore(flags);

- /*
- * If called from the scheduler or NMI context, we can not get console
- * without a possible deadlock.
- *
- * The only exception are Oops messages from NMI context where all
- * relevant locks have been forcefully dropped in
- * try_logbuf_lock_in_nmi(). We have to try to get the console,
- * otherwise the last messages would get lost.
- */
- if (in_sched || (in_nmi() && !oops_in_progress)) {
- __this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT);
- irq_work_queue(this_cpu_ptr(&wake_up_klogd_work));
- } else {
- lockdep_off();
- /*
- * Disable preemption to avoid being preempted while holding
- * console_sem which would prevent anyone from printing to
- * console
- */
- preempt_disable();
-
- /*
- * Try to acquire and then immediately release the console
- * semaphore. The release will print out buffers and wake up
- * /dev/kmsg and syslog() users.
- */
- if (console_trylock_for_printk())
- console_unlock();
- preempt_enable();
- lockdep_on();
- }
+ vprintk_poke_loggers(in_sched);

return printed_len;
}
--
1.8.5.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/