[PATCH v4 1/3] can: rockchip_canfd: prevent TX stall on echo skb failure
Cunhao Lu <[email protected]> Thu, 30 Jul 2026 23:50:41 +0800
| Newsgroups | org.kernel.vger.linux-can,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-rockchip,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
rkcanfd_start_xmit() advances tx_head and requests transmission even when can_put_echo_skb() fails. This creates a pending TX entry without the echo skb that the RXSTX completion path needs to match the self-received frame. The entry cannot be completed, and the netdev TX queue can remain stopped after the two-entry software FIFO fills. Do not advance tx_head or request transmission if the echo skb cannot be installed, and account the frame as dropped. This depends on the standalone can_put_echo_skb() ownership fix. It makes the remaining -EINVAL path consume the skb and was posted at: Link: https://lore.kernel.org/linux-can/[email protected] Fixes: b6661d73290c ("can: rockchip_canfd: add TX PATH") Cc: [email protected] Signed-off-by: Cunhao Lu <[email protected]> --- Changes in v4: - Split the can_put_echo_skb() ownership fix into a standalone patch. - Rely on the standalone patch for error-path skb ownership. - Drop the redundant error message from rkcanfd_start_xmit(). --- drivers/net/can/rockchip/rockchip_canfd-tx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/rockchip/rockchip_canfd-tx.c b/drivers/net/can/rockchip/rockchip_canfd-tx.c index 12200dcfd338..b1954b72560c 100644 --- a/drivers/net/can/rockchip/rockchip_canfd-tx.c +++ b/drivers/net/can/rockchip/rockchip_canfd-tx.c @@ -125,8 +125,11 @@ netdev_tx_t rkcanfd_start_xmit(struct sk_buff *skb, struct net_device *ndev) frame_len = can_skb_get_frame_len(skb); err = can_put_echo_skb(skb, ndev, tx_head, frame_len); - if (!err) - netdev_sent_queue(priv->ndev, frame_len); + if (err) { + ndev->stats.tx_dropped++; + return NETDEV_TX_OK; + } + netdev_sent_queue(priv->ndev, frame_len); WRITE_ONCE(priv->tx_head, priv->tx_head + 1); -- 2.34.1