···118118 * from scratch.119119 */120120121121+/* Counter of active nbcon emergency contexts. */122122+static atomic_t nbcon_cpu_emergency_cnt = ATOMIC_INIT(0);123123+121124/**122125 * nbcon_state_set - Helper function to set the console state123126 * @con: Console to update···11661163 if (kthread_should_stop())11671164 return true;1168116511661166+ /*11671167+ * Block the kthread when the system is in an emergency or panic mode.11681168+ * It increases the chance that these contexts would be able to show11691169+ * the messages directly. And it reduces the risk of interrupted writes11701170+ * where the context with a higher priority takes over the nbcon console11711171+ * ownership in the middle of a message.11721172+ */11731173+ if (unlikely(atomic_read(&nbcon_cpu_emergency_cnt)) ||11741174+ unlikely(panic_in_progress()))11751175+ return false;11761176+11691177 cookie = console_srcu_read_lock();1170117811711179 flags = console_srcu_read_flags(con);···12271213 do {12281214 if (kthread_should_stop())12291215 return 0;12161216+12171217+ /*12181218+ * Block the kthread when the system is in an emergency or panic12191219+ * mode. See nbcon_kthread_should_wakeup() for more details.12201220+ */12211221+ if (unlikely(atomic_read(&nbcon_cpu_emergency_cnt)) ||12221222+ unlikely(panic_in_progress()))12231223+ goto wait_for_event;1230122412311225 backlog = false;12321226···15271505 ctxt->prio = nbcon_get_default_prio();15281506 ctxt->allow_unsafe_takeover = allow_unsafe_takeover;1529150715301530- if (!nbcon_context_try_acquire(ctxt, false))15311531- return -EPERM;15321532-15331508 while (nbcon_seq_read(con) < stop_seq) {15091509+ if (!nbcon_context_try_acquire(ctxt, false))15101510+ return -EPERM;15111511+15341512 /*15351513 * nbcon_emit_next_record() returns false when the console was15361514 * handed over or taken over. In both cases the context is no···15381516 */15391517 if (!nbcon_emit_next_record(&wctxt, true))15401518 return -EAGAIN;15191519+15201520+ nbcon_context_release(ctxt);1541152115421522 if (!ctxt->backlog) {15431523 /* Are there reserved but not yet finalized records? */···15491525 }15501526 }1551152715521552- nbcon_context_release(ctxt);15531528 return err;15541529}15551530···1678165516791656 preempt_disable();1680165716581658+ atomic_inc(&nbcon_cpu_emergency_cnt);16591659+16811660 cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting();16821661 (*cpu_emergency_nesting)++;16831662}···16941669 unsigned int *cpu_emergency_nesting;1695167016961671 cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting();16971697-16981672 if (!WARN_ON_ONCE(*cpu_emergency_nesting == 0))16991673 (*cpu_emergency_nesting)--;16741674+16751675+ /*16761676+ * Wake up kthreads because there might be some pending messages16771677+ * added by other CPUs with normal priority since the last flush16781678+ * in the emergency context.16791679+ */16801680+ if (!WARN_ON_ONCE(atomic_read(&nbcon_cpu_emergency_cnt) == 0)) {16811681+ if (atomic_dec_return(&nbcon_cpu_emergency_cnt) == 0) {16821682+ struct console_flush_type ft;16831683+16841684+ printk_get_console_flush_type(&ft);16851685+ if (ft.nbcon_offload)16861686+ nbcon_kthreads_wake();16871687+ }16881688+ }1700168917011690 preempt_enable();17021691}