]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: devmem: don't call queue stop / start when the interface is down
authorJakub Kicinski <kuba@kernel.org>
Thu, 6 Feb 2025 22:56:36 +0000 (14:56 -0800)
committerJakub Kicinski <kuba@kernel.org>
Sat, 8 Feb 2025 01:21:02 +0000 (17:21 -0800)
We seem to be missing a netif_running() check from the devmem
installation path. Starting a queue on a stopped device makes
no sense. We still want to be able to allocate the memory, just
to test that the device is indeed setting up the page pools
in a memory provider compatible way.

This is not a bug fix, because existing drivers check if
the interface is down as part of the ops. But new drivers
shouldn't have to do this, as long as they can correctly
alloc/free while down.

Reviewed-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20250206225638.1387810-3-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/netdev_queues.h
net/core/netdev_rx_queue.c

index b02bb9f109d5e39c3a60be2def2268da3c6f749c..73d3401261a62b2e8f706a38f13a2e02643a5e4f 100644 (file)
@@ -117,6 +117,10 @@ struct netdev_stat_ops {
  *
  * @ndo_queue_stop:    Stop the RX queue at the specified index. The stopped
  *                     queue's memory is written at the specified address.
+ *
+ * Note that @ndo_queue_mem_alloc and @ndo_queue_mem_free may be called while
+ * the interface is closed. @ndo_queue_start and @ndo_queue_stop will only
+ * be called for an interface which is open.
  */
 struct netdev_queue_mgmt_ops {
        size_t                  ndo_queue_mem_size;
index d421abe06c03003f41f4e4b49699bf83512ff36c..ddd54e1e72897fc6a5b082aa45f154caadb01708 100644 (file)
@@ -38,13 +38,17 @@ int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx)
        if (err)
                goto err_free_new_queue_mem;
 
-       err = qops->ndo_queue_stop(dev, old_mem, rxq_idx);
-       if (err)
-               goto err_free_new_queue_mem;
-
-       err = qops->ndo_queue_start(dev, new_mem, rxq_idx);
-       if (err)
-               goto err_start_queue;
+       if (netif_running(dev)) {
+               err = qops->ndo_queue_stop(dev, old_mem, rxq_idx);
+               if (err)
+                       goto err_free_new_queue_mem;
+
+               err = qops->ndo_queue_start(dev, new_mem, rxq_idx);
+               if (err)
+                       goto err_start_queue;
+       } else {
+               swap(new_mem, old_mem);
+       }
 
        qops->ndo_queue_mem_free(dev, old_mem);