From: David Laight <david.laight.linux@gmail.com>
To: Paul Mbewe <paultyson.mbewe@ziehl-abegg.de>
Cc: <linux-serial@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<gregkh@linuxfoundation.org>, <jirislaby@kernel.org>,
<hvilleneuve@dimonoff.com>, <stable@vger.kernel.org>,
Tobias Gannert <tobias.gannert@ziehl-abegg.de>,
Joachim Knorr <joachim.knorr@ziehl-abegg.de>
Subject: Re: [PATCH 2/2] serial: sc16is7xx: set TX FIFO trigger level to half FIFO to prevent underruns
Date: Tue, 23 Jun 2026 13:45:36 +0100 [thread overview]
Message-ID: <20260623134536.24dca506@pumpkin> (raw)
In-Reply-To: <20260623112225.82386-3-paultyson.mbewe@ziehl-abegg.de>
On Tue, 23 Jun 2026 13:22:25 +0200
Paul Mbewe <paultyson.mbewe@ziehl-abegg.de> wrote:
> The THRI interrupt (IER[1]) fires when the TX FIFO free space reaches the
> configured threshold. With the reset default (TLR=0), the chip falls back
> to the FCR TX trigger of 8 free spaces (FCR[5:4]=00), causing THRI to
> assert after every 8 bytes drain from the FIFO.
>
> At 115200 baud 8N1, 8 bytes drain in 694 us. On slow single-core SPI
> hosts, the combined latency of an SPI IIR read, TXLVL read, and 8-byte
> THR write per interrupt, plus kthread scheduling jitter, can exceed this
> window on a loaded system. When the kthread cannot refill the FIFO within
> 694 us, the FIFO empties and produces an idle gap on the TX line.
That seems strange.
The earlier interrupt (8 free fifo spaces) ought to make it less likely
that the fifo will underrun.
Are you sure it isn't the other way around?
So the interrupt happens when there are 8 bytes left in the fifo.
With a 64 byte fifo each interrupt would fill at least 56 bytes.
Increasing it to 32 (bytes left in the fifo) gives more time for the
interrupt latency (etc), but reduces the number of bytes written by
each isr to at least 32.
The other possibility is some error passing the level sensitive 'fifo empty'
state through to scheduling the kthread.
It may well be that the system interrupt latency is small enough that you
can take the interrupt at 'half full', and that the associated reduction
in the number of interrupts makes the system behave better.
But this isn't what the commit message says.
David
>
> This violates the Modbus RTU specification, which treats any intra-frame
> silence longer than 1.5 character times (~130 us at 115200 baud) as a
> frame boundary, causing receivers to fragment frames and report CRC errors.
> Oscilloscope measurements confirmed a 757 us inter-burst gap during
> continuous transmission without this fix.
>
> Setting the TX trigger to 32 free spaces (half FIFO) via TLR[3:0]=8
> widens the refill window to 2778 us at 115200 baud, reducing THRI events
> per 256-byte frame from ~32 to ~8 and eliminating the underrun.
>
> Only TLR[3:0] is written; TLR[7:4] is left at zero, so the RX trigger
> retains its FCR default. Only TX interrupt timing is affected.
>
> While increasing the SPI clock would also reduce per-round-trip latency,
> the driver should work correctly regardless of SPI speed. The fix belongs
> in the driver.
>
> Tested on i.MX6ULL (ARM Cortex-A7, single-core) with SC16IS752IBS over
> SPI at 1 MHz, 115200 baud 8N1, 256-byte Modbus RTU frames under production
> load:
>
> IRQ thread (irq/134-spi2.0): ~15-17% -> ~5% (~67% reduction)
> sys CPU: ~51-61% -> ~19-28% (~55% reduction)
> load average: ~2.0-2.2 -> ~0.65-1.3
>
> No mid-frame gaps observed after fix. Without fix, oscilloscope confirmed
> 757 us inter-burst gaps causing Modbus frame fragmentation.
>
> Cc: stable@vger.kernel.org
> Reported-by: Tobias Gannert <tobias.gannert@ziehl-abegg.de>
> Tested-by: Tobias Gannert <tobias.gannert@ziehl-abegg.de>
> Reviewed-by: Joachim Knorr <joachim.knorr@ziehl-abegg.de>
> Signed-off-by: Paul Mbewe <paultyson.mbewe@ziehl-abegg.de>
> ---
> drivers/tty/serial/sc16is7xx.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
> index 395a219280be..476e0dd3fa7f 100644
> --- a/drivers/tty/serial/sc16is7xx.c
> +++ b/drivers/tty/serial/sc16is7xx.c
> @@ -1196,6 +1196,16 @@ static int sc16is7xx_startup(struct uart_port *port)
> SC16IS7XX_TCR_RX_RESUME(24) |
> SC16IS7XX_TCR_RX_HALT(48));
>
> + /*
> + * Set TX FIFO trigger level to 32 spaces (half FIFO) via TLR. The reset
> + * default (TLR=0) falls back to the FCR TX trigger of 8 free spaces,
> + * requiring ~8 SPI round-trips per 64-byte FIFO load. On slow single-core
> + * SPI hosts, this accumulated latency can cause a TX FIFO underrun gap
> + * between bursts.
> + */
> + sc16is7xx_port_write(port, SC16IS7XX_TLR_REG,
> + SC16IS7XX_TLR_TX_TRIGGER(32));
> +
> /* Disable TCR/TLR access */
> sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, SC16IS7XX_MCR_TCRTLR_BIT, 0);
>
next prev parent reply other threads:[~2026-06-23 12:45 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-23 11:22 [PATCH 0/2] serial: sc16is7xx: fix TX inter-frame gaps on SPI UARTs Paul Mbewe
2026-06-23 11:22 ` [PATCH 1/2] serial: sc16is7xx: fix TX gap caused by kfifo circular buffer wrap-around Paul Mbewe
2026-06-23 11:22 ` [PATCH 2/2] serial: sc16is7xx: set TX FIFO trigger level to half FIFO to prevent underruns Paul Mbewe
2026-06-23 12:45 ` David Laight [this message]
2026-06-23 14:01 ` Paul Mbewe
2026-06-23 15:07 ` David Laight
2026-06-23 17:13 ` Paul Mbewe
2026-06-23 18:42 ` David Laight
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=20260623134536.24dca506@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=hvilleneuve@dimonoff.com \
--cc=jirislaby@kernel.org \
--cc=joachim.knorr@ziehl-abegg.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=paultyson.mbewe@ziehl-abegg.de \
--cc=stable@vger.kernel.org \
--cc=tobias.gannert@ziehl-abegg.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox