All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Ogness <john.ogness@linutronix.de>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jirislaby@kernel.org>
Cc: "Andy Shevchenko" <andy.shevchenko@gmail.com>,
	"Petr Mladek" <pmladek@suse.com>,
	"Sebastian Andrzej Siewior" <bigeasy@linutronix.de>,
	linux-kernel@vger.kernel.org,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
	"Hugo Villeneuve" <hvilleneuve@dimonoff.com>,
	"Fushuai Wang" <wangfushuai@baidu.com>,
	"Kees Cook" <kees@kernel.org>,
	"Stepan Ionichev" <sozdayvek@gmail.com>,
	linux-serial@vger.kernel.org
Subject: Re: [PATCH tty v9 1/2] serial: 8250: Switch to nbcon console, take 2
Date: Fri, 24 Jul 2026 15:39:49 +0206	[thread overview]
Message-ID: <87o6fwms02.fsf@jogness.linutronix.de> (raw)
In-Reply-To: <20260724103654.133654-2-john.ogness@linutronix.de>

On 2026-07-24, Sashiko wrote:
>> diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
>> index c0e8a4efbdcc8..5042a8e8c6fb1 100644
>> --- a/drivers/tty/serial/8250/8250_core.c
>> +++ b/drivers/tty/serial/8250/8250_core.c
>> @@ -584,13 +609,19 @@ void serial8250_suspend_port(int line)
>>  	struct uart_8250_port *up = &serial8250_ports[line];
>>  	struct uart_port *port = &up->port;
>>  
>> -	if (!console_suspend_enabled && uart_console(port) &&
>> -	    port->type != PORT_8250) {
>> -		unsigned char canary = 0xa5;
>> +	if (uart_console(port)) {
>> +		/* No irq_work may be queued when suspending */
>> +		scoped_guard(uart_port_lock_irq, port)
>> +			up->console_msr_work_allow = false;
>> +		irq_work_sync(&up->console_msr_work);
>
> Does clearing up->console_msr_work_allow under uart_port_lock_irq
> properly serialize against serial8250_console_write()?

Yes.

> Since serial8250_console_write() performs atomic writes without taking
> the port lock, could a delayed execution check
> up->console_msr_work_allow locklessly, get preempted or delayed, and
> then serial8250_suspend_port() clear the flag and call irq_work_sync()
> before the delayed thread resumes?

No. uart_port_lock_irq() also acquires nbcon ownership. That is what
synchronizes against serial8250_console_write() when atomic printing.

>> diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
>> index 8c241ec7f4f29..855a7aa48c2d2 100644
>> --- a/drivers/tty/serial/8250/8250_port.c
>> +++ b/drivers/tty/serial/8250/8250_port.c
>> @@ -3198,13 +3218,28 @@ void serial8250_set_defaults(struct uart_8250_port *up)
>>  }
>>  EXPORT_SYMBOL_GPL(serial8250_set_defaults);
>>  
>> -void serial8250_fifo_wait_for_lsr_thre(struct uart_8250_port *up, unsigned int count)
>> +void serial8250_fifo_wait_for_lsr_thre(struct uart_8250_port *up,
>> +				       struct nbcon_write_context *wctxt,
>> +				       unsigned int count)
>>  {
>>  	unsigned int i;
>>  
>> +	/*
>> +	 * For console writing, enter/exit an unsafe section for each byte
>> +	 * in order to pass the ownership as quickly as possible if a higher
>> +	 * priority context wants ownership. Otherwise, an attempt to take
>> +	 * over the ownership might timeout. The new owner will wait for
>> +	 * UART_LSR_THRE before reusing the fifo.
>> +	 */
>>  	for (i = 0; i < count; i++) {
>> +		if (wctxt && !nbcon_enter_unsafe(wctxt))
>> +			return;
>> +
>>  		if (wait_for_lsr(up, UART_LSR_THRE))
>>  			return;
>
> Does this early return on success bypass the cleanup of the unsafe
> section?
>
> If wait_for_lsr() returns true, wouldn't
> serial8250_fifo_wait_for_lsr_thre() return immediately without calling
> nbcon_exit_unsafe(wctxt)?
>
> Could this resource leak of the nbcon unsafe state prevent other
> contexts from taking over ownership?

It simply has the effect of joining this unsafe section with the next
one. In this case it really wouldn't matter. But still, it was not my
intention. I will fix this for v10.

How I plan for it to look for v10:

	for (i = 0; i < count; i++) {
		bool tx_ready;

		if (wctxt && !nbcon_enter_unsafe(wctxt))
			return;

		tx_ready = wait_for_lsr(up, UART_LSR_THRE);

		if (wctxt)
			nbcon_exit_unsafe(wctxt);

		if (tx_ready)
			break;
	}

I am wondering if we should add a WARN_ON_ONCE() to nbcon_enter_unsafe()
if the context is already unsafe. It is a simple one-liner. That would
at least catch these kinds of mistakes during runtime. (I would do that
in a separate printk patch, not in this series.)

>> @@ -3378,11 +3469,25 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
>>  	 *	call it if we have saved something in the saved flags
>>  	 *	while processing with interrupts off.
>>  	 */
>> -	if (up->msr_saved_flags)
>> -		serial8250_modem_status(up);
>> +	if (up->msr_saved_flags) {
>> +		if (is_atomic) {
>> +			/*
>> +			 * For atomic, MSR handling must be deferred to
>> +			 * irq_work because this may be a context that does
>> +			 * not permit waking up tasks.
>> +			 *
>> +			 * But no irq_work may be queued when suspending.
>> +			 * In that case, the MSR handling will occur during
>> +			 * resume in serial8250_resume_port().
>> +			 */
>> +			if (up->console_msr_work_allow)
>> +				irq_work_queue(&up->console_msr_work);
>
> This is where the lockless read of up->console_msr_work_allow occurs.
>
> If execution is delayed immediately after checking this flag, could
> the port be suspended and irq_work_sync() finish before
> irq_work_queue() is called here?

No. Both the reader and writer must first aquire exclusive nbcon
ownership. Also, WRT @console_msr_work_allow, both reader and writer are
even in unsafe sections and so cannot lose ownership except for on a
hostile takeover during the final unsafe flush of a panic.

John

  reply	other threads:[~2026-07-24 13:33 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-24 10:36 [PATCH tty v9 0/2] Convert 8250 to NBCON, take 2 John Ogness
2026-07-24 10:36 ` [PATCH tty v9 1/2] serial: 8250: Switch to nbcon console, " John Ogness
2026-07-24 13:33   ` John Ogness [this message]
2026-07-24 10:36 ` [PATCH tty v9 2/2] Revert "serial: 8250: drop lockdep annotation from serial8250_clear_IER()" John Ogness

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o6fwms02.fsf@jogness.linutronix.de \
    --to=john.ogness@linutronix.de \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=bigeasy@linutronix.de \
    --cc=gregkh@linuxfoundation.org \
    --cc=hvilleneuve@dimonoff.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=jirislaby@kernel.org \
    --cc=kees@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=pmladek@suse.com \
    --cc=sozdayvek@gmail.com \
    --cc=wangfushuai@baidu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.