Re: [PATCH printk v2 04/18] printk: nbcon: Introduce printing kthreads

From: Petr Mladek
Date: Wed Jun 12 2024 - 07:34:02 EST


On Wed 2024-06-12 13:24:24, John Ogness wrote:
> On 2024-06-12, Petr Mladek <pmladek@xxxxxxxx> wrote:
> >> > After all, I would add two comments, like these:
> >> >
> >> > <proposal-2>
> >> > /*
> >> > * Any access to the console device is serialized either by
> >> > * device_lock() or console context or both.
> >> > */
> >> > kt = kthread_run(nbcon_kthread_func, con, "pr/%s%d", con->name,
> >> > con->index);
> >> > [...]
> >> >
> >> > /*
> >> > * Some users check con->kthread to decide whether to flush
> >> > * the messages directly using con->write_atomic(). But they
> >> > * do so only when the console is already in @console_list.
> >> > */
> >>
> >> I do not understand how @console_list is related to racing between
> >> non-thread and thread. kthreads are not only created during
> >> registration. For example, they can be created much later when the last
> >> boot console unregisters.
> >
> > I had in mind two particular code paths:
> >
> > 1. The check of con->kthread in nbcon_device_release() before
> > calling __nbcon_atomic_flush_pending_con().
> >
> > But it is called only when __uart_port_using_nbcon() returns true.
> > And it would fail when nbcon_kthread_create() is called because
> >
> > checks hlist_unhashed_lockless(&up->cons->node)
> >
> > would fail. Which checks of the console is in @console_list
> >
> >
> > 2. The following check in console_flush_all()
> >
> > if ((flags & CON_NBCON) && con->kthread)
> > continue;
> >
> > The result affects whether the legacy flush would call
> > nbcon_legacy_emit_next_record().
> >
> > But this is called only for_each_console_srcu(con)
> > => it could not race with nbcon_kthread_create()
> > because this console is not in @console_list at this moment.
> >
> > By other words, I was curious whether some other code paths might
> > call con->write_atomic() while the kthread is already running.
> >
> > It is not that important because it would be safe anyway.
> > I was checking this before I realized that it would be safe.
>
> Yes, it must be safe because it can happen at any time. For example,
> when flushing after an emergency section.
>
> > Anyway, the information about that the console is not in @console_list
> > when we set con->kthread still looks useful.
>
> Except that it is not always true. If boot consoles are registered, the
> kthread is created later, after the console _is_ in
> @console_list. Setting con->kthread really has nothing to do with
> @console_list.

Right. I have missed this.

> > At minimum, the check would be racy if the console was on the list.
>
> The con->kthread check _is_ racey, but it doesn't matter. Perhaps you
> just want to make it clear that it is racey but it does not matter.
>
> How about:
>
> /*
> * Some users check con->kthread to decide whether to flush
> * the messages directly using con->write_atomic(). Although
> * racey, such a check for that purpose is safe because both
> * threaded and atomic printing are serialized by the
> * console context.
> */
> con->kthread = kt;

Yes, it sounds good.

Best Regards,
Petr