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>pull/1354/merge
parent
4349cf0df3
commit
62627bf0ca
|
|
@ -664,7 +664,7 @@ static inline bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt) { return
|
||||||
static inline void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt) { }
|
static inline void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt) { }
|
||||||
static inline bool nbcon_kdb_try_acquire(struct console *con,
|
static inline bool nbcon_kdb_try_acquire(struct console *con,
|
||||||
struct nbcon_write_context *wctxt) { return false; }
|
struct nbcon_write_context *wctxt) { return false; }
|
||||||
static inline void nbcon_kdb_release(struct console *con) { }
|
static inline void nbcon_kdb_release(struct nbcon_write_context *wctxt) { }
|
||||||
static inline bool console_is_usable(struct console *con, short flags,
|
static inline bool console_is_usable(struct console *con, short flags,
|
||||||
bool use_atomic) { return false; }
|
bool use_atomic) { return false; }
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -589,12 +589,28 @@ static void kdb_msg_write(const char *msg, int msg_len)
|
||||||
*/
|
*/
|
||||||
cookie = console_srcu_read_lock();
|
cookie = console_srcu_read_lock();
|
||||||
for_each_console_srcu(c) {
|
for_each_console_srcu(c) {
|
||||||
if (!(console_srcu_read_flags(c) & CON_ENABLED))
|
short flags = console_srcu_read_flags(c);
|
||||||
|
|
||||||
|
if (!console_is_usable(c, flags, true))
|
||||||
continue;
|
continue;
|
||||||
if (c == dbg_io_ops->cons)
|
if (c == dbg_io_ops->cons)
|
||||||
continue;
|
continue;
|
||||||
if (!c->write)
|
|
||||||
|
if (flags & CON_NBCON) {
|
||||||
|
struct nbcon_write_context wctxt = { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not continue if the console is NBCON and the context
|
||||||
|
* can't be acquired.
|
||||||
|
*/
|
||||||
|
if (!nbcon_kdb_try_acquire(c, &wctxt))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
nbcon_write_context_set_buf(&wctxt, (char *)msg, msg_len);
|
||||||
|
|
||||||
|
c->write_atomic(c, &wctxt);
|
||||||
|
nbcon_kdb_release(&wctxt);
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* Set oops_in_progress to encourage the console drivers to
|
* Set oops_in_progress to encourage the console drivers to
|
||||||
* disregard their internal spin locks: in the current calling
|
* disregard their internal spin locks: in the current calling
|
||||||
|
|
@ -607,6 +623,7 @@ static void kdb_msg_write(const char *msg, int msg_len)
|
||||||
++oops_in_progress;
|
++oops_in_progress;
|
||||||
c->write(c, msg, msg_len);
|
c->write(c, msg, msg_len);
|
||||||
--oops_in_progress;
|
--oops_in_progress;
|
||||||
|
}
|
||||||
touch_nmi_watchdog();
|
touch_nmi_watchdog();
|
||||||
}
|
}
|
||||||
console_srcu_read_unlock(cookie);
|
console_srcu_read_unlock(cookie);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue