Messages in this thread Patch in this message | | | From | Petr Mladek <> | Subject | [PATCH 10/10] printk: Split console call from vprintk_emit() | Date | Mon, 25 May 2015 14:46:33 +0200 |
| |
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@suse.cz> --- 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
| |