gve: Make the GQ RX free queue funcs idempotent
authorShailend Chand <shailend@google.com>
Wed, 1 May 2024 23:25:41 +0000 (23:25 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 5 May 2024 13:35:33 +0000 (14:35 +0100)
Although this is not fixing any existing double free bug, making these
functions idempotent allows for a simpler implementation of future ndo
hooks that act on a single queue.

Tested-by: Mina Almasry <almasrymina@google.com>
Reviewed-by: Praveen Kaligineedi <pkaligineedi@google.com>
Reviewed-by: Harshitha Ramamurthy <hramamurthy@google.com>
Signed-off-by: Shailend Chand <shailend@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/google/gve/gve_rx.c

index 9b56e89c4f430a7a4b09406f38649b56b4312341..0a3f88170411692e4974ded8f54cc667a7d3a71b 100644 (file)
@@ -30,6 +30,9 @@ static void gve_rx_unfill_pages(struct gve_priv *priv,
        u32 slots = rx->mask + 1;
        int i;
 
+       if (!rx->data.page_info)
+               return;
+
        if (rx->data.raw_addressing) {
                for (i = 0; i < slots; i++)
                        gve_rx_free_buffer(&priv->pdev->dev, &rx->data.page_info[i],
@@ -69,20 +72,26 @@ static void gve_rx_free_ring_gqi(struct gve_priv *priv, struct gve_rx_ring *rx,
        int idx = rx->q_num;
        size_t bytes;
 
-       bytes = sizeof(struct gve_rx_desc) * cfg->ring_size;
-       dma_free_coherent(dev, bytes, rx->desc.desc_ring, rx->desc.bus);
-       rx->desc.desc_ring = NULL;
+       if (rx->desc.desc_ring) {
+               bytes = sizeof(struct gve_rx_desc) * cfg->ring_size;
+               dma_free_coherent(dev, bytes, rx->desc.desc_ring, rx->desc.bus);
+               rx->desc.desc_ring = NULL;
+       }
 
-       dma_free_coherent(dev, sizeof(*rx->q_resources),
-                         rx->q_resources, rx->q_resources_bus);
-       rx->q_resources = NULL;
+       if (rx->q_resources) {
+               dma_free_coherent(dev, sizeof(*rx->q_resources),
+                                 rx->q_resources, rx->q_resources_bus);
+               rx->q_resources = NULL;
+       }
 
        gve_rx_unfill_pages(priv, rx, cfg);
 
-       bytes = sizeof(*rx->data.data_ring) * slots;
-       dma_free_coherent(dev, bytes, rx->data.data_ring,
-                         rx->data.data_bus);
-       rx->data.data_ring = NULL;
+       if (rx->data.data_ring) {
+               bytes = sizeof(*rx->data.data_ring) * slots;
+               dma_free_coherent(dev, bytes, rx->data.data_ring,
+                                 rx->data.data_bus);
+               rx->data.data_ring = NULL;
+       }
 
        kvfree(rx->qpl_copy_pool);
        rx->qpl_copy_pool = NULL;