From: sashiko-bot@kernel.org
To: "Tapio Reijonen" <tapio.reijonen@vaisala.com>
Cc: linux-serial@vger.kernel.org
Subject: Re: [PATCH v7 9/9] serial: max310x: don't transmit while an RS485 reconfigure is pending
Date: Mon, 05 Oct 2026 13:41:09 +0000 [thread overview]
Message-ID: <20261005134109.EE6A11F00893@smtp.kernel.org> (raw)
In-Reply-To: <20261005-max310x-rs485-sw-delay-v7-9-6ae392eca08c@vaisala.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] tty: max310x: tx_work bypasses rs485_pending gate allowing transmission during reconfigure
- [High] tty: max310x: TOCTOU race on chip_tx_empty causes incorrect state rewind
--
commit 7203e556ec43dfcd637262655ece112903f9eb73
Author: Tapio Reijonen <tapio.reijonen@vaisala.com>
serial: max310x: don't transmit while an RS485 reconfigure is pending
This commit defers transmissions while an RS485 configuration is pending,
leaving data in the kfifo until rs_work finishes reprogramming the registers.
It drops the direct tx_work kick in the disable path in favor of restarting
the transmission once the configuration is fully applied.
> diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
> index 5fdb9dfca6027..833ab4d461235 100644
> --- a/drivers/tty/serial/max310x.c
> +++ b/drivers/tty/serial/max310x.c
[ ... ]
> @@ -979,6 +980,16 @@ static void max310x_start_tx(struct uart_port *port)
> if (one->tx_teardown)
> return;
>
> + /*
> + * An RS485 reconfigure is scheduled but not applied yet: transmitting
> + * now would use the old path against half-programmed registers - a
> + * TIOCSRS485 switching paths followed immediately by a write puts the
> + * data on the wire with the transceiver released. Leave the data in
> + * the kfifo; rs_work restarts TX once the configuration is applied.
> + */
> + if (one->rs485_pending)
> + return;
[Severity: High]
Does this check sufficiently gate the transmission?
While this defers synchronous writes, a TXEMPTY interrupt can asynchronously
queue tx_work during the pending RS485 reconfiguration:
max310x_port_irq()
if (ists & MAX310X_IRQ_TXEMPTY_BIT)
schedule_work(&s->p[portno].tx_work);
If tx_work executes concurrently with max310x_rs_proc(), it calls
max310x_handle_tx() which pumps data from xmit_fifo to the hardware FIFO:
max310x_handle_tx()
while (!kfifo_is_empty(&tport->xmit_fifo)) {
/* Limit to space available in TX FIFO */
txlen = max310x_port_read(port, MAX310X_TXFIFOLVL_REG);
...
}
Since max310x_handle_tx() runs without holding a synchronizing lock or
checking the rs485_pending flag, can this regression allow background workers
to bypass the deferral mechanism and transmit data with a half-programmed
transceiver?
[ ... ]
> @@ -1465,6 +1479,31 @@ static void max310x_rs_proc(struct work_struct *ws)
>
> max310x_port_update(&one->port, MAX310X_MODE2_REG,
> MAX310X_MODE2_ECHOSUPR_BIT, mode2);
> +
> + /*
> + * The configuration is applied: release any TX that start_tx()
> + * deferred while the reconfigure was pending, now on the right
> + * path. start_tx() can drop and retake the lock through the
> + * uart_port API - a raw spinlock guard here would unbalance it.
> + */
> + chip_tx_empty = !max310x_port_read(&one->port,
> + MAX310X_TXFIFOLVL_REG);
> +
> + uart_port_lock_irqsave(&one->port, &flags);
> + one->rs485_pending = false;
> + if (one->port.x_char ||
> + !kfifo_is_empty(&one->port.state->port.xmit_fifo)) {
> + /*
> + * A send state adopted without chip data is the deferred
> + * write itself: restart it as a fresh envelope so the
> + * before-send delay is honoured.
> + */
> + if (chip_tx_empty &&
> + READ_ONCE(one->tx_state) == MAX310X_TX_SEND)
> + WRITE_ONCE(one->tx_state, MAX310X_TX_OFF);
[Severity: High]
Is it possible for chip_tx_empty to be stale here due to a race with tx_work?
The TX FIFO level is read outside the lock. Concurrently, tx_work can execute
max310x_handle_tx() and write new data to the chip FIFO without acquiring
port->lock.
When max310x_rs_proc() then acquires port->lock, it uses the stale
chip_tx_empty value to rewind the transmission state to MAX310X_TX_OFF, even
though data is already being transmitted.
Can this incorrect rewind introduce a regression by breaking the timing
envelope, causing data to hit the RS485 bus without the configured
before-send delay?
> + max310x_start_tx(&one->port);
> + }
> + uart_port_unlock_irqrestore(&one->port, flags);
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261005-max310x-rs485-sw-delay-v7-0-6ae392eca08c@vaisala.com?part=9
next prev parent reply other threads:[~2026-10-05 13:41 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-05 13:19 [PATCH v7 0/9] (no cover subject) Tapio Reijonen
2026-10-05 13:19 ` [PATCH v7 1/9] serial: max310x: don't clobber the TX break bit in set_termios Tapio Reijonen
2026-10-05 13:27 ` sashiko-bot
2026-10-05 15:57 ` Hugo Villeneuve
2026-10-06 4:06 ` Tapio Reijonen
2026-10-06 13:42 ` Hugo Villeneuve
2026-10-08 9:06 ` Tapio Reijonen
2026-10-05 13:19 ` [PATCH v7 2/9] serial: max310x: assert the transceiver during a break Tapio Reijonen
2026-10-05 13:39 ` sashiko-bot
2026-10-05 13:19 ` [PATCH v7 3/9] serial: max310x: centralize the RS485 transceiver programming Tapio Reijonen
2026-10-05 13:19 ` [PATCH v7 4/9] serial: max310x: convert RS485 delays from milliseconds to bit-times Tapio Reijonen
2026-10-05 13:33 ` sashiko-bot
2026-10-05 13:19 ` [PATCH v7 5/9] serial: max310x: stop the transmitter before powering down in shutdown Tapio Reijonen
2026-10-05 13:34 ` sashiko-bot
2026-10-05 13:19 ` [PATCH v7 6/9] serial: max310x: support active-low RTS on the hardware path Tapio Reijonen
2026-10-05 13:34 ` sashiko-bot
2026-10-05 13:19 ` [PATCH v7 7/9] serial: max310x: schedule tx_work directly from the IRQ handler Tapio Reijonen
2026-10-05 13:30 ` sashiko-bot
2026-10-05 13:19 ` [PATCH v7 8/9] serial: max310x: drive RTS in software when hardware delays are too short Tapio Reijonen
2026-10-05 13:40 ` sashiko-bot
2026-10-05 13:19 ` [PATCH v7 9/9] serial: max310x: don't transmit while an RS485 reconfigure is pending Tapio Reijonen
2026-10-05 13:41 ` sashiko-bot [this message]
2026-10-05 13:37 ` [PATCH v7 0/9] (no cover subject) Tapio Reijonen
2026-10-05 15:51 ` Hugo Villeneuve
2026-10-06 4:03 ` Tapio Reijonen
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=20261005134109.EE6A11F00893@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=tapio.reijonen@vaisala.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.