net: lan743x: Fix memleak issue when GSO enabled
authorThangaraj Samynathan <thangaraj.s@microchip.com>
Tue, 29 Apr 2025 05:25:27 +0000 (10:55 +0530)
committerJakub Kicinski <kuba@kernel.org>
Thu, 1 May 2025 14:04:58 +0000 (07:04 -0700)
Always map the `skb` to the LS descriptor. Previously skb was
mapped to EXT descriptor when the number of fragments is zero with
GSO enabled. Mapping the skb to EXT descriptor prevents it from
being freed, leading to a memory leak

Fixes: 23f0703c125b ("lan743x: Add main source files for new lan743x driver")
Signed-off-by: Thangaraj Samynathan <thangaraj.s@microchip.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20250429052527.10031-1-thangaraj.s@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/microchip/lan743x_main.h

index 23760b613d3ecfa5ac59d539e99b0c707ead40a2..e2d6bfb5d69334f3ec4bcbf8e6a2ba9c53147145 100644 (file)
@@ -1815,6 +1815,7 @@ static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx,
        if (nr_frags <= 0) {
                tx->frame_data0 |= TX_DESC_DATA0_LS_;
                tx->frame_data0 |= TX_DESC_DATA0_IOC_;
+               tx->frame_last = tx->frame_first;
        }
        tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
        tx_descriptor->data0 = cpu_to_le32(tx->frame_data0);
@@ -1884,6 +1885,7 @@ static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx,
                tx->frame_first = 0;
                tx->frame_data0 = 0;
                tx->frame_tail = 0;
+               tx->frame_last = 0;
                return -ENOMEM;
        }
 
@@ -1924,16 +1926,18 @@ static void lan743x_tx_frame_end(struct lan743x_tx *tx,
            TX_DESC_DATA0_DTYPE_DATA_) {
                tx->frame_data0 |= TX_DESC_DATA0_LS_;
                tx->frame_data0 |= TX_DESC_DATA0_IOC_;
+               tx->frame_last = tx->frame_tail;
        }
 
-       tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
-       buffer_info = &tx->buffer_info[tx->frame_tail];
+       tx_descriptor = &tx->ring_cpu_ptr[tx->frame_last];
+       buffer_info = &tx->buffer_info[tx->frame_last];
        buffer_info->skb = skb;
        if (time_stamp)
                buffer_info->flags |= TX_BUFFER_INFO_FLAG_TIMESTAMP_REQUESTED;
        if (ignore_sync)
                buffer_info->flags |= TX_BUFFER_INFO_FLAG_IGNORE_SYNC;
 
+       tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
        tx_descriptor->data0 = cpu_to_le32(tx->frame_data0);
        tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
        tx->last_tail = tx->frame_tail;
index 7f73d66854bee4c8077ebbddad0fc4591ffc03e4..db5fc73e41cca5ab5eaa207a2acde750d0addf73 100644 (file)
@@ -980,6 +980,7 @@ struct lan743x_tx {
        u32             frame_first;
        u32             frame_data0;
        u32             frame_tail;
+       u32             frame_last;
 
        struct lan743x_tx_buffer_info *buffer_info;