[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aXPyiOMxClprdOQM@smile.fi.intel.com>
Date: Sat, 24 Jan 2026 00:13:28 +0200
From: Andy Shevchenko <andriy.shevchenko@...ux.intel.com>
To: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Jiri Slaby <jirislaby@...nel.org>, linux-serial@...r.kernel.org,
qianfan Zhao <qianfanguijin@....com>,
Adriana Nicolae <adriana@...sta.com>, linux-kernel@...r.kernel.org,
"Bandal, Shankar" <shankar.bandal@...el.com>,
"Murthy, Shanth" <shanth.murthy@...el.com>
Subject: Re: [PATCH 4/6] serial: 8250_dw: Rework IIR_NO_INT handling to stop
interrupt storm
On Fri, Jan 23, 2026 at 07:27:37PM +0200, Ilpo Järvinen wrote:
> INTC10EE UART can end up into an interrupt storm where it reports
> IIR_NO_INT (0x1). If the storm happens during active UART operation, it
> is promptly stopped by IIR value change due to Rx or Tx events.
> However, when there is no activity, either due to idle serial line or
> due to specific circumstances such as during shutdown that writes
> IER=0, there is nothing to stop the storm.
>
> During shutdown the storm is particularly problematic because
> serial8250_do_shutdown() calls synchronize_irq() that will hang in
> waiting for the storm to finish which never happens.
>
> This problem can also result in triggering a warning:
>
> irq 45: nobody cared (try booting with the "irqpoll" option)
> [...snip...]
> handlers:
> serial8250_interrupt
> Disabling IRQ #45
>
> Normal means to reset interrupt status by reading LSR, MSR, USR, or RX
> register do not result in the UART deasserting the IRQ.
>
> Add a quirk to INTC10EE UARTs to enable Tx interrupts if UART's Tx is
> currently empty and inactive. Rework IIR_NO_INT to keep track of the
> number of consecutive IIR_NO_INT, and on third one perform the quirk.
> Enabling Tx interrupts should change IIR value from IIR_NO_INT to
> IIR_THRI which has been observed to stop the storm.
...
> + u64 no_int_count;
Why so big?
...
> + d->no_int_count++;
> + if (d->no_int_count > 2 && quirks & DW_UART_QUIRK_IER_KICK)
> + dw8250_quirk_ier_kick(p);
Usual way is to use modulo. And perhaps use 4 for the sake of avoiding
division:
if (d->no_int_count == 3 && quirks & DW_UART_QUIRK_IER_KICK)
dw8250_quirk_ier_kick(p);
d->no_int_count = (d->no_int_count + 1) % 4;
where 4 may be defined with meaningful name. With that u8 is more than enough.
> return 0;
--
With Best Regards,
Andy Shevchenko
Powered by blists - more mailing lists