Re: [PATCH printk 1/3] printk: Introduce console sync mode

From: Petr Mladek

Date: Tue Jul 14 2026 - 10:29:32 EST


On Fri 2026-07-10 16:51:51, John Ogness wrote:
> Sometimes it is desirable that console printing occurs synchronously
> in the context of the printk() caller. Introduce a "sync mode" for
> nbcon consoles that provide safe atomic_write() implementations. A
> new console flag CON_SYNC shows if a console is operating in this
> mode.
>
> When in sync mode, a console will flush directly within vprintk_emit()
> using the same mechanism as emergency printing. If the console
> hardware is currently owned by another context, the flushing will
> occur when that context releases ownership (just as is the case with
> non-panic emergency printing).
>
> If CON_SYNC is set for a legacy console driver or a nbcon console
> driver that does not provide a safe atomic_write(), the flag is
> cleared upon console registration and a message is logged that the
> console does not support sync mode.
>
> --- a/include/linux/console.h
> +++ b/include/linux/console.h
> @@ -180,6 +180,7 @@ static inline void con_debug_leave(void) { }
> * constraints.
> * @CON_NBCON_ATOMIC_UNSAFE: The write_atomic() callback is not safe and is
> * therefore only used by nbcon_atomic_flush_unsafe().
> + * @CON_SYNC: Print using write_atomic() from the printk() calling context.
> */
> enum cons_flags {
> CON_PRINTBUFFER = BIT(0),
> @@ -192,6 +193,7 @@ enum cons_flags {
> CON_SUSPENDED = BIT(7),
> CON_NBCON = BIT(8),
> CON_NBCON_ATOMIC_UNSAFE = BIT(9),
> + CON_SYNC = BIT(10),

My first feeling was that this was an overhead. But it might make
sense to keep only one console synchronous, ...

> diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
> index 4b03b019cd5ee..77abb98042648 100644
> --- a/kernel/printk/nbcon.c
> +++ b/kernel/printk/nbcon.c
> @@ -1919,8 +1942,15 @@ void nbcon_device_release(struct console *con)
> * usable throughout flushing.
> */
> cookie = console_srcu_read_lock();
> - printk_get_console_flush_type(&ft);
> - if (console_is_usable(con, console_srcu_read_flags(con), true) &&
> + flags = console_srcu_read_flags(con);
> + if (unlikely(flags & CON_SYNC)) {
> + /* Sync consoles will always perform nbcon_atomic flushing. */
> + memset(&ft, 0, sizeof(ft));
> + ft.nbcon_atomic = true;

They have to use the legacy loop when boot consoles are still
registered, see below.

> + } else {
> + printk_get_console_flush_type(&ft);
> + }
> + if (console_is_usable(con, flags, true) &&
> !ft.nbcon_offload &&
> prb_read_valid(prb, nbcon_seq_read(con), NULL)) {
> /*
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -2456,6 +2463,8 @@ asmlinkage int vprintk_emit(int facility, int level,
>
> if (ft.nbcon_atomic)
> nbcon_atomic_flush_pending();
> + else if (have_sync_console)
> + nbcon_sync_flush_pending();

Again. we should not do this when boot consoles are still
registered.

Also I think that we need to flush it in many more situations.
In general, it should be needed everywhere
printk_get_console_flush_type() is called for nbcon consoles
in a context with NBCON_PRIO_NORMAL, see below.

BTW: I wonder if this would work when more CPUs are adding
messages in parallel. I guess that they would fight for
the printing context. But I guess that they will
eventually finish the printing.

It is a bit different from the best effort approach used
by the legacy loop. Synchronous nbcon console will cause
that printk() might serialize CPUs...

It might be acceptable because this mode should not be
normally used. But we should at least document it.

> if (ft.nbcon_offload)
> nbcon_kthreads_wake();


I think that we should integrate this into
printk_get_console_flush_type(). We could solve the problem
with per-console flags the same way as for other flags,
by global variables:

+ have_nbcon_sync_console
+ have_nbcon_async_console

I wondered how it might look like. And I wanted to try AI.
I came with the following patch on top of this patchset.

The first version was generated by Claude, including the commit
message. Later, I modified the code a lot, and the commit message
a bit, by hand.

It is relatively complex. But I think that it is the prize for
the feature. And I think that the modification of
printk_get_console_flush_type() better fits the existing
design and helps to make sure that we handle it well
in all situations.

Feel free to integrate it into the first patch. Or maybe,
we could add the two have_nbcon* variables in a separate
patch, first, ...

Here is the patch: