diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/printk/internal.h | 2 | ||||
-rw-r--r-- | kernel/printk/nbcon.c | 20 | ||||
-rw-r--r-- | kernel/printk/printk.c | 2 |
3 files changed, 23 insertions, 1 deletions
diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 84706c1c934b..7679e18f24b3 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -153,6 +153,8 @@ static inline bool console_is_usable(struct console *con, short flags) { return #endif /* CONFIG_PRINTK */ +extern bool have_boot_console; + extern struct printk_buffers printk_shared_pbufs; /** diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index d09c084c9af4..269aeed18064 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -1326,10 +1326,30 @@ EXPORT_SYMBOL_GPL(nbcon_device_try_acquire); void nbcon_device_release(struct console *con) { struct nbcon_context *ctxt = &ACCESS_PRIVATE(con, nbcon_device_ctxt); + int cookie; if (!nbcon_context_exit_unsafe(ctxt)) return; nbcon_context_release(ctxt); + + /* + * This context must flush any new records added while the console + * was locked. The console_srcu_read_lock must be taken to ensure + * the console is usable throughout flushing. + */ + cookie = console_srcu_read_lock(); + if (console_is_usable(con, console_srcu_read_flags(con)) && + prb_read_valid(prb, nbcon_seq_read(con), NULL)) { + if (!have_boot_console) { + __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb)); + } else if (!is_printk_legacy_deferred()) { + if (console_trylock()) + console_unlock(); + } else { + printk_trigger_flush(); + } + } + console_srcu_read_unlock(cookie); } EXPORT_SYMBOL_GPL(nbcon_device_release); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index f08bf5e82fc7..7c9f8f6e1738 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -469,7 +469,7 @@ static DEFINE_MUTEX(syslog_lock); * the console lock. This is because boot consoles and nbcon consoles may * have mapped the same hardware. */ -static bool have_boot_console; +bool have_boot_console; #ifdef CONFIG_PRINTK DECLARE_WAIT_QUEUE_HEAD(log_wait); |