···185185 bool legacy_offload;186186};187187188188+extern bool console_irqwork_blocked;189189+188190/*189191 * Identify which console flushing methods should be used in the context of190192 * the caller.···198196 switch (nbcon_get_default_prio()) {199197 case NBCON_PRIO_NORMAL:200198 if (have_nbcon_console && !have_boot_console) {201201- if (printk_kthreads_running)199199+ if (printk_kthreads_running && !console_irqwork_blocked)202200 ft->nbcon_offload = true;203201 else204202 ft->nbcon_atomic = true;···208206 if (have_legacy_console || have_boot_console) {209207 if (!is_printk_legacy_deferred())210208 ft->legacy_direct = true;211211- else209209+ else if (!console_irqwork_blocked)212210 ft->legacy_offload = true;213211 }214212 break;···221219 if (have_legacy_console || have_boot_console) {222220 if (!is_printk_legacy_deferred())223221 ft->legacy_direct = true;224224- else222222+ else if (!console_irqwork_blocked)225223 ft->legacy_offload = true;226224 }227225 break;
+8-1
kernel/printk/nbcon.c
···13021302 if (!printk_kthreads_running)13031303 return;1304130413051305+ /*13061306+ * It is not allowed to call this function when console irq_work13071307+ * is blocked.13081308+ */13091309+ if (WARN_ON_ONCE(console_irqwork_blocked))13101310+ return;13111311+13051312 cookie = console_srcu_read_lock();13061313 for_each_console_srcu(con) {13071314 if (!(console_srcu_read_flags(con) & CON_NBCON))···18991892 if (console_trylock())19001893 console_unlock();19011894 } else if (ft.legacy_offload) {19021902- printk_trigger_flush();18951895+ defer_console_output();19031896 }19041897 }19051898 console_srcu_read_unlock(cookie);
+66-17
kernel/printk/printk.c
···462462/* See printk_legacy_allow_panic_sync() for details. */463463bool legacy_allow_panic_sync;464464465465+/* Avoid using irq_work when suspending. */466466+bool console_irqwork_blocked;467467+465468#ifdef CONFIG_PRINTK466469DECLARE_WAIT_QUEUE_HEAD(log_wait);467470static DECLARE_WAIT_QUEUE_HEAD(legacy_wait);···23932390 /* If called from the scheduler, we can not call up(). */23942391 if (level == LOGLEVEL_SCHED) {23952392 level = LOGLEVEL_DEFAULT;23962396- ft.legacy_offload |= ft.legacy_direct;23932393+ ft.legacy_offload |= ft.legacy_direct && !console_irqwork_blocked;23972394 ft.legacy_direct = false;23982395 }23992396···2429242624302427 if (ft.legacy_offload)24312428 defer_console_output();24322432- else24292429+ else if (!console_irqwork_blocked)24332430 wake_up_klogd();2434243124352432 return printed_len;···27332730{27342731 struct console *con;2735273227332733+ if (console_suspend_enabled)27342734+ pr_info("Suspending console(s) (use no_console_suspend to debug)\n");27352735+27362736+ /*27372737+ * Flush any console backlog and then avoid queueing irq_work until27382738+ * console_resume_all(). Until then deferred printing is no longer27392739+ * triggered, NBCON consoles transition to atomic flushing, and27402740+ * any klogd waiters are not triggered.27412741+ */27422742+ pr_flush(1000, true);27432743+ console_irqwork_blocked = true;27442744+27362745 if (!console_suspend_enabled)27372746 return;27382738- pr_info("Suspending console(s) (use no_console_suspend to debug)\n");27392739- pr_flush(1000, true);2740274727412748 console_list_lock();27422749 for_each_console(con)···27672754 struct console_flush_type ft;27682755 struct console *con;2769275627702770- if (!console_suspend_enabled)27712771- return;27722772-27732773- console_list_lock();27742774- for_each_console(con)27752775- console_srcu_write_flags(con, con->flags & ~CON_SUSPENDED);27762776- console_list_unlock();27772777-27782757 /*27792779- * Ensure that all SRCU list walks have completed. All printing27802780- * contexts must be able to see they are no longer suspended so27812781- * that they are guaranteed to wake up and resume printing.27582758+ * Allow queueing irq_work. After restoring console state, deferred27592759+ * printing and any klogd waiters need to be triggered in case there27602760+ * is now a console backlog.27822761 */27832783- synchronize_srcu(&console_srcu);27622762+ console_irqwork_blocked = false;27632763+27642764+ if (console_suspend_enabled) {27652765+ console_list_lock();27662766+ for_each_console(con)27672767+ console_srcu_write_flags(con, con->flags & ~CON_SUSPENDED);27682768+ console_list_unlock();27692769+27702770+ /*27712771+ * Ensure that all SRCU list walks have completed. All printing27722772+ * contexts must be able to see they are no longer suspended so27732773+ * that they are guaranteed to wake up and resume printing.27742774+ */27752775+ synchronize_srcu(&console_srcu);27762776+ }2784277727852778 printk_get_console_flush_type(&ft);27862779 if (ft.nbcon_offload)27872780 nbcon_kthreads_wake();27882781 if (ft.legacy_offload)27892782 defer_console_output();27832783+ else27842784+ wake_up_klogd();2790278527912786 pr_flush(1000, true);27922787}···45804559 if (!printk_percpu_data_ready())45814560 return;4582456145624562+ /*45634563+ * It is not allowed to call this function when console irq_work45644564+ * is blocked.45654565+ */45664566+ if (WARN_ON_ONCE(console_irqwork_blocked))45674567+ return;45684568+45834569 preempt_disable();45844570 /*45854571 * Guarantee any new records can be seen by tasks preparing to wait···46434615 __wake_up_klogd(PRINTK_PENDING_WAKEUP | PRINTK_PENDING_OUTPUT);46444616}4645461746184618+/**46194619+ * printk_trigger_flush - Attempt to flush printk buffer to consoles.46204620+ *46214621+ * If possible, flush the printk buffer to all consoles in the caller's46224622+ * context. If offloading is available, trigger deferred printing.46234623+ *46244624+ * This is best effort. Depending on the system state, console states,46254625+ * and caller context, no actual flushing may result from this call.46264626+ */46464627void printk_trigger_flush(void)46474628{46484648- defer_console_output();46294629+ struct console_flush_type ft;46304630+46314631+ printk_get_console_flush_type(&ft);46324632+ if (ft.nbcon_atomic)46334633+ nbcon_atomic_flush_pending();46344634+ if (ft.nbcon_offload)46354635+ nbcon_kthreads_wake();46364636+ if (ft.legacy_direct) {46374637+ if (console_trylock())46384638+ console_unlock();46394639+ }46404640+ if (ft.legacy_offload)46414641+ defer_console_output();46494642}4650464346514644int vprintk_deferred(const char *fmt, va_list args)