]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: ena: clean up XDP TX queues when regular TX setup fails
authorDawei Feng <dawei.feng@seu.edu.cn>
Tue, 16 Jun 2026 14:24:24 +0000 (22:24 +0800)
committerJakub Kicinski <kuba@kernel.org>
Fri, 19 Jun 2026 01:11:22 +0000 (18:11 -0700)
create_queues_with_size_backoff() creates XDP TX queues before setting
up the regular TX path. If the subsequent allocation or creation of
regular TX queues fails, the error handling paths omit the teardown of the
XDP TX queues, leading to a resource leak.

Fix this by explicitly destroying the XDP TX queue subset at the two
missing failure points.

The bug was first flagged by an experimental analysis tool we are
developing for kernel memory-management bugs while analyzing
v6.13-rc1. The tool is still under development and is not yet publicly
available. Manual inspection confirms that the bug is still
present in v7.1-rc7.

An x86_64 allyesconfig build showed no new warnings. As we do not have
an ENA device to test with, no runtime testing was able to be performed.

Fixes: 548c4940b9f1 ("net: ena: Implement XDP_TX action")
Cc: stable@vger.kernel.org
Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
Reviewed-by: Arthur Kiyanovski <akiyano@amazon.com>
Tested-by: Arthur Kiyanovski <akiyano@amazon.com>
Link: https://patch.msgid.link/20260616142424.4005130-1-dawei.feng@seu.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/amazon/ena/ena_netdev.c

index 92d149d4f0917fd8641a4c904c86f82f371e05a3..5d05020a6d058bea68cd19b6dd835a567311dea5 100644 (file)
@@ -752,6 +752,18 @@ static void ena_destroy_all_tx_queues(struct ena_adapter *adapter)
        }
 }
 
+static void ena_destroy_xdp_tx_queues(struct ena_adapter *adapter)
+{
+       u16 ena_qid;
+       int i;
+
+       for (i = adapter->xdp_first_ring;
+            i < adapter->xdp_first_ring + adapter->xdp_num_queues; i++) {
+               ena_qid = ENA_IO_TXQ_IDX(i);
+               ena_com_destroy_io_queue(adapter->ena_dev, ena_qid);
+       }
+}
+
 static void ena_destroy_all_rx_queues(struct ena_adapter *adapter)
 {
        u16 ena_qid;
@@ -2078,14 +2090,21 @@ static int create_queues_with_size_backoff(struct ena_adapter *adapter)
                rc = ena_setup_tx_resources_in_range(adapter,
                                                     0,
                                                     adapter->num_io_queues);
-               if (rc)
+               if (rc) {
+                       ena_destroy_xdp_tx_queues(adapter);
+                       ena_free_all_io_tx_resources_in_range(adapter,
+                                                             adapter->xdp_first_ring,
+                                                             adapter->xdp_num_queues);
                        goto err_setup_tx;
+               }
 
                rc = ena_create_io_tx_queues_in_range(adapter,
                                                      0,
                                                      adapter->num_io_queues);
-               if (rc)
+               if (rc) {
+                       ena_destroy_xdp_tx_queues(adapter);
                        goto err_create_tx_queues;
+               }
 
                rc = ena_setup_all_rx_resources(adapter);
                if (rc)