diff options
-rw-r--r-- | kernel/printk/printk.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index ffb56c2150b0..b8634a153d1d 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -463,6 +463,14 @@ static int console_msg_format = MSG_FORMAT_DEFAULT; /* syslog_lock protects syslog_* variables and write access to clear_seq. */ static DEFINE_MUTEX(syslog_lock); +/* + * Specifies if a boot console is registered. If boot consoles are present, + * nbcon consoles cannot print simultaneously and must be synchronized by + * the console lock. This is because boot consoles and nbcon consoles may + * have mapped the same hardware. + */ +static bool have_boot_console; + #ifdef CONFIG_PRINTK DECLARE_WAIT_QUEUE_HEAD(log_wait); /* All 3 protected by @syslog_lock. */ @@ -3610,6 +3618,9 @@ void register_console(struct console *newcon) newcon->seq = init_seq; } + if (newcon->flags & CON_BOOT) + have_boot_console = true; + /* * If another context is actively using the hardware of this new * console, it will not be aware of the nbcon synchronization. This @@ -3680,7 +3691,9 @@ EXPORT_SYMBOL(register_console); static int unregister_console_locked(struct console *console) { bool use_device_lock = (console->flags & CON_NBCON) && console->write_atomic; + bool found_boot_con = false; unsigned long flags; + struct console *c; int res; lockdep_assert_console_list_lock_held(); @@ -3738,6 +3751,17 @@ static int unregister_console_locked(struct console *console) if (console->exit) res = console->exit(console); + /* + * With this console gone, the global flags tracking registered + * console types may have changed. Update them. + */ + for_each_console(c) { + if (c->flags & CON_BOOT) + found_boot_con = true; + } + if (!found_boot_con) + have_boot_console = found_boot_con; + return res; } |