It might take ages until users see messages from NMI context. They cannot
be flushed to the console because the operation involves taking and
releasing a bunch of locks. Everything gets fixed by the followup printk
in normal context but it is not predictable.

The same problem has printk_sched() and this patch reuses the existing
solution.

There is no special printk() variant for NMI context. Hence the IRQ work
need to get queued from vprintk_emit().

Signed-off-by: Petr Mladek <[email protected]>
---
 kernel/printk/printk.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index bf2abdda5869..c2ae9ff388ae 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1554,9 +1554,6 @@ int printk_deferred(const char *fmt, ...)
        va_start(args, fmt);
        r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, 0, fmt, args);
        va_end(args);
-
-       __this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT);
-       irq_work_queue(this_cpu_ptr(&wake_up_klogd_work));
        preempt_enable();
 
        return r;
@@ -1880,7 +1877,10 @@ asmlinkage int vprintk_emit(int facility, int level,
         * If called from the scheduler or NMI context, we can not get console
         * without a possible deadlock.
         */
-       if (!in_sched && !in_nmi()) {
+       if (in_sched || in_nmi()) {
+               __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
-- 
1.8.5.6

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

Reply via email to