Commit 62627bf0 authored by Marcos Paulo de Souza's avatar Marcos Paulo de Souza Committed by Petr Mladek
Browse files

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: default avatarPetr Mladek <pmladek@suse.com>
Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
Reviewed-by: default avatarJohn Ogness <john.ogness@linutronix.de>
Signed-off-by: default avatarMarcos 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: default avatarPetr Mladek <pmladek@suse.com>
parent 4349cf0d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 bool nbcon_kdb_try_acquire(struct console *con,
					 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,
				     bool use_atomic) { return false; }
#endif
+32 −15
Original line number Diff line number Diff line
@@ -589,12 +589,28 @@ static void kdb_msg_write(const char *msg, int msg_len)
	 */
	cookie = console_srcu_read_lock();
	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;
		if (c == dbg_io_ops->cons)
			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;

			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
			 * 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;
			c->write(c, msg, msg_len);
			--oops_in_progress;
		}
		touch_nmi_watchdog();
	}
	console_srcu_read_unlock(cookie);