[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <875xsdf7zm.fsf@jogness.linutronix.de>
Date: Wed, 07 Aug 2024 03:21:57 +0206
From: John Ogness <john.ogness@...utronix.de>
To: Petr Mladek <pmladek@...e.com>
Cc: Sergey Senozhatsky <senozhatsky@...omium.org>, Steven Rostedt
<rostedt@...dmis.org>, Thomas Gleixner <tglx@...utronix.de>,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH printk v7 24/35] printk: nbcon: Flush new records on
device_release()
On 2024-08-05, Petr Mladek <pmladek@...e.com> wrote:
>> + /*
>> + * 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();
>
> nbcon_device_release() is going to be called in uart_port_unlock*()
> still under the port->lock.
>
> => It smells with a potential deadlock. The console_flush_all() in
> console_unlock() might want to flush this console under the
> port->lock as well.
>
> And it almost happens because nbcon_legacy_emit_next_record()
> might eventually take con->device_lock() when called in
> a task context.
>
> It will not happen here because this code uses console_trylock()
> which would set @console_may_schedule to false.
Exactly. That is an important point. We must never try to invoke the
write_thread() callback while holding a spinlock.
> Anyway, it would look more safe when the flush was done after releasing
> the port->lock.
Even then we could never invoke the write_thread() callback because the
caller may be holding other spinlocks. If we cannot safely call
console_lock(), we cannot take the device lock. The atomic callback must
be used and that means the port lock cannot be involved in the
console_trylock().
John
Powered by blists - more mailing lists