All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: mkl@pengutronix.de
Cc: Jakub Kicinski <kuba@kernel.org>,
	netdev@vger.kernel.org, davem@davemloft.net,
	linux-can@vger.kernel.org, kernel@pengutronix.de,
	blbllhy@gmail.com, AutonomousCodeSecurity@microsoft.com,
	xmei5@asu.edu
Subject: Re: [PATCH net 06/14] can: rockchip_canfd: retry the outstanding TX buffer
Date: Thu, 27 Aug 2026 12:44:08 -0700	[thread overview]
Message-ID: <20260827194408.4023732-1-kuba@kernel.org> (raw)
In-Reply-To: <20260826121036.2706424-7-mkl@pengutronix.de>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
can: rockchip_canfd: retry the outstanding TX buffer

This changes rkcanfd_xmit_retry() to use rkcanfd_get_tx_tail() instead of
rkcanfd_get_tx_head() when building the TX_REQ command, so that the
erratum 6 workaround re-requests the buffer that is actually outstanding
now that the TX FIFO depth is two.

Link: https://patch.msgid.link/tencent_2CCE005FC440BF8026599A6999EC04BE1107@qq.com

> diff --git a/drivers/net/can/rockchip/rockchip_canfd-tx.c b/drivers/net/can/rockchip/rockchip_canfd-tx.c
> index 86fa8f2e1c8ba..fc338ea865feb 100644
> --- a/drivers/net/can/rockchip/rockchip_canfd-tx.c
> +++ b/drivers/net/can/rockchip/rockchip_canfd-tx.c
> @@ -57,8 +57,8 @@ static void rkcanfd_start_xmit_write_cmd(const struct rkcanfd_priv *priv,
>  
>  void rkcanfd_xmit_retry(struct rkcanfd_priv *priv)
>  {
> -	const unsigned int tx_head = rkcanfd_get_tx_head(priv);
> -	const u32 reg_cmd = RKCANFD_REG_CMD_TX_REQ(tx_head);
> +	const unsigned int tx_tail = rkcanfd_get_tx_tail(priv);
> +	const u32 reg_cmd = RKCANFD_REG_CMD_TX_REQ(tx_tail);
>  
>  	rkcanfd_start_xmit_write_cmd(priv, reg_cmd);
>  }

[Severity: Medium]

This isn't a bug introduced by this patch, but with rkcanfd_xmit_retry()
now aiming at the tx_tail buffer, is the buffer it re-requests the same
one that rkcanfd_start_xmit() may be arming at that moment?

rkcanfd_xmit_retry() is reached from the hard-IRQ handler, since
rkcanfd_open() registers it non-threaded:

	err = request_irq(ndev->irq, rkcanfd_irq, IRQF_SHARED, ndev->name, priv);

and rkcanfd_irq()->rkcanfd_handle_rx_int()->rkcanfd_rxstx_filter() calls
rkcanfd_xmit_retry() for the erratum 6 case. At this commit there is no
lock covering priv->tx_head, priv->tx_tail or the register writes.

Two interleavings look possible.

First, rkcanfd_start_xmit_write_cmd() is not atomic:

	if (priv->devtype_data.quirks & RKCANFD_QUIRK_RK3568_ERRATUM_12)
		rkcanfd_write(priv, RKCANFD_REG_MODE, priv->reg_mode_default |
			      RKCANFD_REG_MODE_SPACE_RX_MODE);

	rkcanfd_write(priv, RKCANFD_REG_CMD, reg_cmd);

	if (priv->devtype_data.quirks & RKCANFD_QUIRK_RK3568_ERRATUM_12)
		rkcanfd_write(priv, RKCANFD_REG_MODE, priv->reg_mode_default);

If the interrupt path runs this sequence while the transmit path is
between its own MODE and CMD writes, the restore of reg_mode_default
lands before the other context's CMD write. Does that silently drop the
erratum 12 workaround for that frame? rk3568v2 carries both
RKCANFD_QUIRK_RK3568_ERRATUM_6 and RKCANFD_QUIRK_RK3568_ERRATUM_12.

Second, rkcanfd_start_xmit() publishes the new head before issuing the
command:

	WRITE_ONCE(priv->tx_head, priv->tx_head + 1);

	rkcanfd_start_xmit_write_cmd(priv, reg_cmd);

If the interrupt path completes the previous frame (advancing tx_tail)
in that window, rkcanfd_xmit_retry() now selects the buffer whose CMD
write has not been issued yet. Can that produce a second TX request for
the same buffer, a duplicated frame on the wire, and a desynchronized
echo ring, with rkcanfd_tx_tail_is_eff() then hitting the

	"%s: echo_skb[%u]=NULL tx_head=0x%08x tx_tail=0x%08x\n"

path?

For what it is worth, this appears to be addressed later in the same
series by the change that adds "spinlock_t tx_lock; /* protects tx_head,
tx_tail and echo_skb */" to struct rkcanfd_priv, wraps the
rkcanfd_start_xmit() echo/register/command sequence in
spin_lock_irqsave()/spin_unlock_irqrestore(), takes the same lock in
rkcanfd_rxstx_filter() and adds lockdep_assert_held(&priv->tx_lock) to
rkcanfd_xmit_retry(). Given that ordering, would it be worth noting the
dependency in this patch so that a standalone stable backport of this
change does not land without the locking?

  reply	other threads:[~2026-08-27 19:44 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-26 12:02 [PATCH net 0/14] pull-request: can 2026-08-26 Marc Kleine-Budde
2026-08-26 12:02 ` [PATCH net 01/14] can: dev: can_dropped_invalid_skb: drop CAN XL frames on non-CAN XL devices Marc Kleine-Budde
2026-08-26 12:02 ` [PATCH net 02/14] can: convert unreliable ARPHRD_CAN type checks to robust can_get_ml_priv() Marc Kleine-Budde
2026-08-27 12:10   ` sashiko-bot
2026-08-27 12:41     ` Oliver Hartkopp
2026-08-26 12:02 ` [PATCH net 03/14] can: bittiming: fix divide-by-zero in can_calc_bittiming() Marc Kleine-Budde
2026-08-27 12:10   ` sashiko-bot
2026-08-27 19:44   ` Jakub Kicinski
2026-08-26 12:02 ` [PATCH net 04/14] can: bittiming: fix bitrate error calculation on unsigned operands Marc Kleine-Budde
2026-08-26 12:02 ` [PATCH net 05/14] can: rockchip_canfd: prevent TX stall on echo skb failure Marc Kleine-Budde
2026-08-26 12:02 ` [PATCH net 06/14] can: rockchip_canfd: retry the outstanding TX buffer Marc Kleine-Budde
2026-08-27 19:44   ` Jakub Kicinski [this message]
2026-08-26 12:02 ` [PATCH net 07/14] can: rockchip_canfd: serialize TX state and command writes Marc Kleine-Budde
2026-08-27 19:44   ` Jakub Kicinski
2026-08-26 12:02 ` [PATCH net 08/14] can: skb: make echo skb freeing safe in any IRQ context Marc Kleine-Budde
2026-08-27 12:10   ` sashiko-bot
2026-08-26 12:02 ` [PATCH net 09/14] can: skb: make CAN skb allocation failure paths IRQ-safe Marc Kleine-Budde
2026-08-26 12:02 ` [PATCH net 10/14] can: dev: can_put_echo_skb(): free skb on invalid echo index Marc Kleine-Budde
2026-08-27 12:10   ` sashiko-bot
2026-08-27 17:01     ` Oliver Hartkopp
2026-08-26 12:02 ` [PATCH net 11/14] can: kvaser_pciefd: fix use-after-free in bec poll timer Marc Kleine-Budde
2026-08-27 12:10   ` sashiko-bot
2026-08-27 12:36     ` Marc Kleine-Budde
2026-08-27 12:55       ` Marc Kleine-Budde
2026-08-26 12:02 ` [PATCH net 12/14] can: kvaser_usb: validate command format before parsing in hydra receive path Marc Kleine-Budde
2026-08-27 12:10   ` sashiko-bot
2026-08-27 12:57     ` Marc Kleine-Budde
2026-08-27 19:44   ` Jakub Kicinski
2026-09-10 13:55     ` Cen Zhang (Microsoft Security FORGE Labs)
2026-08-26 12:02 ` [PATCH net 13/14] can: usb: f81604: fix struct f81604_int_data size mismatch Marc Kleine-Budde
2026-08-27 12:10   ` sashiko-bot
2026-08-26 12:02 ` [PATCH net 14/14] can: hi311x: drop hi3110_lock before free_irq() on open failure Marc Kleine-Budde
2026-08-27 12:10   ` sashiko-bot

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=20260827194408.4023732-1-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=AutonomousCodeSecurity@microsoft.com \
    --cc=blbllhy@gmail.com \
    --cc=davem@davemloft.net \
    --cc=kernel@pengutronix.de \
    --cc=linux-can@vger.kernel.org \
    --cc=mkl@pengutronix.de \
    --cc=netdev@vger.kernel.org \
    --cc=xmei5@asu.edu \
    /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.