Re: [PATCH RFC 0/3] printk: Don't flush messages using write_atomic during console registration if kthreads have not been started yet.

Michael Cobb
2025-05-30T10:38:41Z

On Fri, 16 May 2025 at 10:44, John Ogness <john.ogness@linutronix.de> wrote:
> If I understand the problem correctly, it is really due to the "console
> enabled" message that is printed upon registration. For the first
> console, it would perform a full atomic flush, even though it is about
> to create the kthread printer.

Hi John,

Yes, you're correct, when the first nbcon console is registered, any
calls to printk() (made after have_nbcon_console is set and before
printk_kthreads_check_locked() sets printk_kthreads_running) will
trigger an atomic flush.

This can also happen if we attempt to register the console before
printk_set_kthreads_ready() has been called, as
printk_kthreads_check_locked() cannot start printer kthreads yet. In
this case printk() will also flush atomically until kthreads are
ready.

> What if we create the kthread _before_ printing the message. Something
> like the below (untested) changes. Does this also address the issue?

Yes, that works and avoids the atomic flush, however we then lose the
"console [ttyS0] enabled" message on any boot consoles that we are
about to unregister. See the comment above the con_printk() call:

/*
* By unregistering the bootconsoles after we enable the real console
* we get the "console xxx enabled" message on all the consoles -
* boot consoles, real consoles, etc - this is to ensure that end
* users know there might be something in the kernel's log buffer that
* went to the bootconsole (that they do not see on the real console)
*/
con_printk(KERN_INFO, newcon, "enabled\n");

We would then also need to ensure that nowhere in this code path calls
printk(). I can see some places where printk() might be called (mainly
for error reporting). For example, unregister_console_locked(), prints
a "console disabled" message, also in the call to
console_sysfs_notify() (linux/kernel/printk/printk.c:4116),
kernfs_put() calls WARN_ONCE() (linux/fs/kernfs/dir.c:579).

I am worried that by avoiding calling printk() to not trigger a flush,
this might not be robust enough?
Any future changes, even those made outside printk.c if made inside
this code path, can reintroduce an atomic flush just by calling
printk().

Kind regards,

Michael