History

kdb: Adapt kdb_msg_write to work with NBCON consoles

Function kdb_msg_write was calling con->write for any found console, but it won't work on NBCON consoles. In this case we should acquire the ownership of the console using NBCON_PRIO_EMERGENCY, since printing kdb messages should only be interrupted by a panic. At this point, the console is required to use the atomic callback. The console is skipped if the write_atomic callback is not set or if the context could not be acquired. The validation of NBCON is done by the console_is_usable helper. The context is released right after write_atomic finishes. The oops_in_progress handling is only needed in the legacy consoles, so it was moved around the con->write callback.

Marcos Paulo de Souza committed 1 year ago

Commit 62627bf1 parent 4349cf02 files · +33 −16Browse files

Showing the changes to kernel/debug (1 of 2 files). Show all

Unified · Split

kernel/debug/kdb/kdb_io.c+32−15
@@ -589,24 +589,41 @@ static void kdb_msg_write(const char *msg, int msg_len) · 588 unmodified lines
589589 */
590590 cookie = console_srcu_read_lock();
591591 for_each_console_srcu(c) {
592− if (!(console_srcu_read_flags(c) & CON_ENABLED))
592+ short flags = console_srcu_read_flags(c);
593+
594+ if (!console_is_usable(c, flags, true))
593595 continue;
594596 if (c == dbg_io_ops->cons)
595597 continue;
596− if (!c->write)
597− continue;
598− /*
599− * Set oops_in_progress to encourage the console drivers to
600− * disregard their internal spin locks: in the current calling
601− * context the risk of deadlock is a bigger problem than risks
602− * due to re-entering the console driver. We operate directly on
603− * oops_in_progress rather than using bust_spinlocks() because
604− * the calls bust_spinlocks() makes on exit are not appropriate
605− * for this calling context.
606− */
607− ++oops_in_progress;
608− c->write(c, msg, msg_len);
609− --oops_in_progress;
598+
599+ if (flags & CON_NBCON) {
600+ struct nbcon_write_context wctxt = { };
601+
602+ /*
603+ * Do not continue if the console is NBCON and the context
604+ * can't be acquired.
605+ */
606+ if (!nbcon_kdb_try_acquire(c, &wctxt))
607+ continue;
608+
609+ nbcon_write_context_set_buf(&wctxt, (char *)msg, msg_len);
610+
611+ c->write_atomic(c, &wctxt);
612+ nbcon_kdb_release(&wctxt);
613+ } else {
614+ /*
615+ * Set oops_in_progress to encourage the console drivers to
616+ * disregard their internal spin locks: in the current calling
617+ * context the risk of deadlock is a bigger problem than risks
618+ * due to re-entering the console driver. We operate directly on
619+ * oops_in_progress rather than using bust_spinlocks() because
620+ * the calls bust_spinlocks() makes on exit are not appropriate
621+ * for this calling context.
622+ */
623+ ++oops_in_progress;
624+ c->write(c, msg, msg_len);
625+ --oops_in_progress;
626+ }
610627 touch_nmi_watchdog();
611628 }
612629 console_srcu_read_unlock(cookie);