]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: enetc: keep track of correct Tx BD count in enetc_map_tx_tso_buffs()
authorWei Fang <wei.fang@nxp.com>
Mon, 24 Feb 2025 11:12:45 +0000 (19:12 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Mar 2025 15:56:49 +0000 (16:56 +0100)
commit da291996b16ebd10626d4b20288327b743aff110 upstream.

When creating a TSO header, if the skb is VLAN tagged, the extended BD
will be used and the 'count' should be increased by 2 instead of 1.
Otherwise, when an error occurs, less tx_swbd will be freed than the
actual number.

Fixes: fb8629e2cbfc ("net: enetc: add support for software TSO")
Cc: stable@vger.kernel.org
Suggested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Wei Fang <wei.fang@nxp.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Link: https://patch.msgid.link/20250224111251.1061098-3-wei.fang@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/freescale/enetc/enetc.c

index 59d943c1eee7d0c149c61a6872c9785c1351d36a..c262a28fce1192c6632eab3f9035f3ef700c4b7e 100644 (file)
@@ -329,14 +329,15 @@ dma_err:
        return 0;
 }
 
-static void enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
-                                struct enetc_tx_swbd *tx_swbd,
-                                union enetc_tx_bd *txbd, int *i, int hdr_len,
-                                int data_len)
+static int enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
+                               struct enetc_tx_swbd *tx_swbd,
+                               union enetc_tx_bd *txbd, int *i, int hdr_len,
+                               int data_len)
 {
        union enetc_tx_bd txbd_tmp;
        u8 flags = 0, e_flags = 0;
        dma_addr_t addr;
+       int count = 1;
 
        enetc_clear_tx_bd(&txbd_tmp);
        addr = tx_ring->tso_headers_dma + *i * TSO_HEADER_SIZE;
@@ -379,7 +380,10 @@ static void enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
                /* Write the BD */
                txbd_tmp.ext.e_flags = e_flags;
                *txbd = txbd_tmp;
+               count++;
        }
+
+       return count;
 }
 
 static int enetc_map_tx_tso_data(struct enetc_bdr *tx_ring, struct sk_buff *skb,
@@ -511,9 +515,9 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
 
                /* compute the csum over the L4 header */
                csum = enetc_tso_hdr_csum(&tso, skb, hdr, hdr_len, &pos);
-               enetc_map_tx_tso_hdr(tx_ring, skb, tx_swbd, txbd, &i, hdr_len, data_len);
+               count += enetc_map_tx_tso_hdr(tx_ring, skb, tx_swbd, txbd,
+                                             &i, hdr_len, data_len);
                bd_data_num = 0;
-               count++;
 
                while (data_len > 0) {
                        int size;