]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: stmmac: fix transmit interrupt coalescing
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Tue, 24 Feb 2026 09:01:55 +0000 (09:01 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 26 Feb 2026 03:12:34 +0000 (19:12 -0800)
The accounting for transmit frames does not count the descriptors
correctly. It uses:

tx_packets = (tx_q->cur_tx + 1) - first_tx;

however, these are indexes into a circular buffer, so cur_tx can be
less than first_tx, and when that happens, tx_packets becomes a very
large unsigned integer. When this is added to tx_q->tx_count_frames,
it has the effect of reducing the count of frames, possibly causing
it to also wrap to a very large unsigned integer.

Fix this by using CIRC_CNT() to calculate the number of descriptors
used.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/E1vuoIl-0000000Aouz-0ttb@rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index 1a9fdde281f85d9c435612ef246eb0108e39da24..7bf3a8667999c173fc9642a0fa361efbdc698301 100644 (file)
@@ -4516,7 +4516,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
        tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
 
        /* Manage tx mitigation */
-       tx_packets = (tx_q->cur_tx + 1) - first_tx;
+       tx_packets = CIRC_CNT(tx_q->cur_tx + 1, first_tx,
+                             priv->dma_conf.dma_tx_size);
        tx_q->tx_count_frames += tx_packets;
 
        if ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && priv->hwts_tx_en)
@@ -4794,7 +4795,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
         * This approach takes care about the fragments: desc is the first
         * element in case of no SG.
         */
-       tx_packets = (entry + 1) - first_tx;
+       tx_packets = CIRC_CNT(entry + 1, first_tx, priv->dma_conf.dma_tx_size);
        tx_q->tx_count_frames += tx_packets;
 
        if ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && priv->hwts_tx_en)