@@ -462,6 +462,9 @@ bool have_boot_console;
462462/* See printk_legacy_allow_panic_sync() for details. */
463463bool legacy_allow_panic_sync ;
464464
465+ /* Avoid using irq_work when suspending. */
466+ bool console_irqwork_blocked ;
467+
465468#ifdef CONFIG_PRINTK
466469DECLARE_WAIT_QUEUE_HEAD (log_wait );
467470static DECLARE_WAIT_QUEUE_HEAD (legacy_wait );
@@ -2390,7 +2393,7 @@ asmlinkage int vprintk_emit(int facility, int level,
23902393 /* If called from the scheduler, we can not call up(). */
23912394 if (level == LOGLEVEL_SCHED ) {
23922395 level = LOGLEVEL_DEFAULT ;
2393- ft .legacy_offload |= ft .legacy_direct ;
2396+ ft .legacy_offload |= ft .legacy_direct && ! console_irqwork_blocked ;
23942397 ft .legacy_direct = false;
23952398 }
23962399
@@ -2426,7 +2429,7 @@ asmlinkage int vprintk_emit(int facility, int level,
24262429
24272430 if (ft .legacy_offload )
24282431 defer_console_output ();
2429- else
2432+ else if (! console_irqwork_blocked )
24302433 wake_up_klogd ();
24312434
24322435 return printed_len ;
@@ -2730,10 +2733,20 @@ void console_suspend_all(void)
27302733{
27312734 struct console * con ;
27322735
2736+ if (console_suspend_enabled )
2737+ pr_info ("Suspending console(s) (use no_console_suspend to debug)\n" );
2738+
2739+ /*
2740+ * Flush any console backlog and then avoid queueing irq_work until
2741+ * console_resume_all(). Until then deferred printing is no longer
2742+ * triggered, NBCON consoles transition to atomic flushing, and
2743+ * any klogd waiters are not triggered.
2744+ */
2745+ pr_flush (1000 , true);
2746+ console_irqwork_blocked = true;
2747+
27332748 if (!console_suspend_enabled )
27342749 return ;
2735- pr_info ("Suspending console(s) (use no_console_suspend to debug)\n" );
2736- pr_flush (1000 , true);
27372750
27382751 console_list_lock ();
27392752 for_each_console (con )
@@ -2754,26 +2767,34 @@ void console_resume_all(void)
27542767 struct console_flush_type ft ;
27552768 struct console * con ;
27562769
2757- if (!console_suspend_enabled )
2758- return ;
2759-
2760- console_list_lock ();
2761- for_each_console (con )
2762- console_srcu_write_flags (con , con -> flags & ~CON_SUSPENDED );
2763- console_list_unlock ();
2764-
27652770 /*
2766- * Ensure that all SRCU list walks have completed. All printing
2767- * contexts must be able to see they are no longer suspended so
2768- * that they are guaranteed to wake up and resume printing .
2771+ * Allow queueing irq_work. After restoring console state, deferred
2772+ * printing and any klogd waiters need to be triggered in case there
2773+ * is now a console backlog .
27692774 */
2770- synchronize_srcu (& console_srcu );
2775+ console_irqwork_blocked = false;
2776+
2777+ if (console_suspend_enabled ) {
2778+ console_list_lock ();
2779+ for_each_console (con )
2780+ console_srcu_write_flags (con , con -> flags & ~CON_SUSPENDED );
2781+ console_list_unlock ();
2782+
2783+ /*
2784+ * Ensure that all SRCU list walks have completed. All printing
2785+ * contexts must be able to see they are no longer suspended so
2786+ * that they are guaranteed to wake up and resume printing.
2787+ */
2788+ synchronize_srcu (& console_srcu );
2789+ }
27712790
27722791 printk_get_console_flush_type (& ft );
27732792 if (ft .nbcon_offload )
27742793 nbcon_kthreads_wake ();
27752794 if (ft .legacy_offload )
27762795 defer_console_output ();
2796+ else
2797+ wake_up_klogd ();
27772798
27782799 pr_flush (1000 , true);
27792800}
@@ -4559,6 +4580,13 @@ static void __wake_up_klogd(int val)
45594580 if (!printk_percpu_data_ready ())
45604581 return ;
45614582
4583+ /*
4584+ * It is not allowed to call this function when console irq_work
4585+ * is blocked.
4586+ */
4587+ if (WARN_ON_ONCE (console_irqwork_blocked ))
4588+ return ;
4589+
45624590 preempt_disable ();
45634591 /*
45644592 * Guarantee any new records can be seen by tasks preparing to wait
@@ -4615,9 +4643,30 @@ void defer_console_output(void)
46154643 __wake_up_klogd (PRINTK_PENDING_WAKEUP | PRINTK_PENDING_OUTPUT );
46164644}
46174645
4646+ /**
4647+ * printk_trigger_flush - Attempt to flush printk buffer to consoles.
4648+ *
4649+ * If possible, flush the printk buffer to all consoles in the caller's
4650+ * context. If offloading is available, trigger deferred printing.
4651+ *
4652+ * This is best effort. Depending on the system state, console states,
4653+ * and caller context, no actual flushing may result from this call.
4654+ */
46184655void printk_trigger_flush (void )
46194656{
4620- defer_console_output ();
4657+ struct console_flush_type ft ;
4658+
4659+ printk_get_console_flush_type (& ft );
4660+ if (ft .nbcon_atomic )
4661+ nbcon_atomic_flush_pending ();
4662+ if (ft .nbcon_offload )
4663+ nbcon_kthreads_wake ();
4664+ if (ft .legacy_direct ) {
4665+ if (console_trylock ())
4666+ console_unlock ();
4667+ }
4668+ if (ft .legacy_offload )
4669+ defer_console_output ();
46214670}
46224671
46234672int vprintk_deferred (const char * fmt , va_list args )
0 commit comments