Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

printk: nbcon: Allow KDB to acquire the NBCON context

KDB can interrupt any console to execute the "mirrored printing" at any
time, so add an exception to nbcon_context_try_acquire_direct to allow
to get the context if the current CPU is the same as kdb_printf_cpu.

This change will be necessary for the next patch, which fixes
kdb_msg_write to work with NBCON consoles by calling ->write_atomic on
such consoles. But to print it first needs to acquire the ownership of
the console, so nbcon_context_try_acquire_direct is fixed here.

Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Link: https://patch.msgid.link/20251016-nbcon-kgdboc-v6-3-866aac60a80e@suse.com
[pmladek@suse.com: Fix compilation with !CONFIG_KGDB_KDB.]
Signed-off-by: Petr Mladek <pmladek@suse.com>

authored by

Marcos Paulo de Souza and committed by
Petr Mladek
286b113d 49f7d305

+21 -1
+16
include/linux/kdb.h
··· 14 14 */ 15 15 16 16 #include <linux/list.h> 17 + #include <linux/smp.h> 17 18 18 19 /* Shifted versions of the command enable bits are be used if the command 19 20 * has no arguments (see kdb_check_flags). This allows commands, such as ··· 208 207 /* Dynamic kdb shell command registration */ 209 208 extern int kdb_register(kdbtab_t *cmd); 210 209 extern void kdb_unregister(kdbtab_t *cmd); 210 + 211 + /* Return true when KDB as locked for printing a message on this CPU. */ 212 + static inline 213 + bool kdb_printf_on_this_cpu(void) 214 + { 215 + /* 216 + * We can use raw_smp_processor_id() here because the task could 217 + * not get migrated when KDB has locked for printing on this CPU. 218 + */ 219 + return unlikely(READ_ONCE(kdb_printf_cpu) == raw_smp_processor_id()); 220 + } 221 + 211 222 #else /* ! CONFIG_KGDB_KDB */ 212 223 static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } 213 224 static inline void kdb_init(int level) {} 214 225 static inline int kdb_register(kdbtab_t *cmd) { return 0; } 215 226 static inline void kdb_unregister(kdbtab_t *cmd) {} 227 + 228 + static inline bool kdb_printf_on_this_cpu(void) { return false; } 229 + 216 230 #endif /* CONFIG_KGDB_KDB */ 217 231 enum { 218 232 KDB_NOT_INITIALIZED,
+5 -1
kernel/printk/nbcon.c
··· 10 10 #include <linux/export.h> 11 11 #include <linux/init.h> 12 12 #include <linux/irqflags.h> 13 + #include <linux/kdb.h> 13 14 #include <linux/kthread.h> 14 15 #include <linux/minmax.h> 15 16 #include <linux/panic.h> ··· 250 249 * since all non-panic CPUs are stopped during panic(), it 251 250 * is safer to have them avoid gaining console ownership. 252 251 * 253 - * If this acquire is a reacquire (and an unsafe takeover 252 + * One exception is when kdb has locked for printing on this CPU. 253 + * 254 + * Second exception is a reacquire (and an unsafe takeover 254 255 * has not previously occurred) then it is allowed to attempt 255 256 * a direct acquire in panic. This gives console drivers an 256 257 * opportunity to perform any necessary cleanup if they were 257 258 * interrupted by the panic CPU while printing. 258 259 */ 259 260 if (panic_on_other_cpu() && 261 + !kdb_printf_on_this_cpu() && 260 262 (!is_reacquire || cur->unsafe_takeover)) { 261 263 return -EPERM; 262 264 }