Skip to content

Commit 62627bf

Browse files
marcospspmladek
authored andcommitted
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. Suggested-by: Petr Mladek <pmladek@suse.com> Reviewed-by: Petr Mladek <pmladek@suse.com> Reviewed-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com> Link: https://patch.msgid.link/20251016-nbcon-kgdboc-v6-5-866aac60a80e@suse.com [pmladek@suse.com: Fixed compilation with !CONFIG_PRINTK.] Signed-off-by: Petr Mladek <pmladek@suse.com>
1 parent 4349cf0 commit 62627bf

2 files changed

Lines changed: 33 additions & 16 deletions

File tree

include/linux/console.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ static inline bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt) { return
664664
static inline void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt) { }
665665
static inline bool nbcon_kdb_try_acquire(struct console *con,
666666
struct nbcon_write_context *wctxt) { return false; }
667-
static inline void nbcon_kdb_release(struct console *con) { }
667+
static inline void nbcon_kdb_release(struct nbcon_write_context *wctxt) { }
668668
static inline bool console_is_usable(struct console *con, short flags,
669669
bool use_atomic) { return false; }
670670
#endif

kernel/debug/kdb/kdb_io.c

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -589,24 +589,41 @@ static void kdb_msg_write(const char *msg, int msg_len)
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);

0 commit comments

Comments
 (0)