Re: [PATCH 2/3] can: rockchip_canfd: retry the outstanding TX buffer

[email protected] Thu, 30 Jul 2026 06:26:31 +0000
Newsgroups org.kernel.vger.linux-can
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 1 potential issue(=
s) to consider:

Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but there is a data =
race on hardware registers RKCANFD_REG_MODE and RKCANFD_REG_CMD in rkcanfd_=
start_xmit_write_cmd() between softirq and hard IRQ contexts.
--

--- Patch [2]: [PATCH 2/3] can: rockchip_canfd: retry the outstanding TX bu=
ffer ---
commit 008079a4d397736133d0b75cae9351b6c5be751d
Author: Cunhao Lu <[email protected]>

can: rockchip_canfd: retry the outstanding TX buffer

After the FIFO depth was increased to two, tx_head selects the next
free buffer instead of the outstanding one, breaking the erratum 6
workaround. This patch fixes the issue by using tx_tail to select
the outstanding buffer for retransmission.

> diff --git a/drivers/net/can/rockchip/rockchip_canfd-tx.c b/drivers/net/c=
an/rockchip/rockchip_canfd-tx.c
> index d2cbe25c46d6c..c4ecdc9411cc6 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 r=
kcanfd_priv *priv,
> =20
>  void rkcanfd_xmit_retry(struct rkcanfd_priv *priv)
>  {
> -	const unsigned int tx_head =3D rkcanfd_get_tx_head(priv);
> -	const u32 reg_cmd =3D RKCANFD_REG_CMD_TX_REQ(tx_head);
> +	const unsigned int tx_tail =3D rkcanfd_get_tx_tail(priv);
> +	const u32 reg_cmd =3D RKCANFD_REG_CMD_TX_REQ(tx_tail);
> =20
>  	rkcanfd_start_xmit_write_cmd(priv, reg_cmd);

[Severity: High]
This isn't a bug introduced by this patch, but does this call expose a race
condition on the hardware registers between softirq and hardirq contexts?

rkcanfd_start_xmit() runs in softirq context and calls
rkcanfd_start_xmit_write_cmd(), which performs non-atomic register writes
to RKCANFD_REG_MODE. If a hardware RX interrupt preempts execution between
these writes, rkcanfd_irq() (hardirq) will call rkcanfd_xmit_retry()
which also calls rkcanfd_start_xmit_write_cmd().

The hardirq will restore priv->reg_mode_default, so when the softirq
resumes, RKCANFD_REG_CMD is written without the required SPACE_RX_MODE
bit set, bypassing the RK3568 Erratum 12 workaround. Could this lead to
hardware misbehavior under heavy load?

>  }

--=20
Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260730-master-v1-=
[email protected]?part=3D2