net: drop rtnl_lock for queue_mgmt operations
authorStanislav Fomichev <sdf@fomichev.me>
Tue, 11 Mar 2025 14:40:26 +0000 (07:40 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 12 Mar 2025 20:32:35 +0000 (13:32 -0700)
All drivers that use queue API are already converted to use
netdev instance lock. Move netdev instance lock management to
the netlink layer and drop rtnl_lock.

Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Mina Almasry. <almasrymina@google.com>
Link: https://patch.msgid.link/20250311144026.4154277-4-sdf@fomichev.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/netdevsim/netdev.c
net/core/devmem.c
net/core/netdev-genl.c
net/core/netdev_rx_queue.c

index 08ac01d6a5097c9b47e88749dbca3043ae87c4ff..d4dc812eb7e248e3cd4f2307d41e3be78423eecc 100644 (file)
@@ -11381,14 +11381,14 @@ static void bnxt_irq_affinity_notify(struct irq_affinity_notify *notify,
        if (pcie_tph_set_st_entry(irq->bp->pdev, irq->msix_nr, tag))
                return;
 
-       rtnl_lock();
+       netdev_lock(irq->bp->dev);
        if (netif_running(irq->bp->dev)) {
                err = netdev_rx_queue_restart(irq->bp->dev, irq->ring_nr);
                if (err)
                        netdev_err(irq->bp->dev,
                                   "RX queue restart failed: err=%d\n", err);
        }
-       rtnl_unlock();
+       netdev_unlock(irq->bp->dev);
 }
 
 static void bnxt_irq_affinity_release(struct kref *ref)
index d71fd2907cc80d2208a29411188c347351156120..e3152ebe98a233bade539bf7155594f97a7bd6c2 100644 (file)
@@ -787,7 +787,7 @@ nsim_qreset_write(struct file *file, const char __user *data,
        if (ret != 2)
                return -EINVAL;
 
-       rtnl_lock();
+       netdev_lock(ns->netdev);
        if (queue >= ns->netdev->real_num_rx_queues) {
                ret = -EINVAL;
                goto exit_unlock;
@@ -801,7 +801,7 @@ nsim_qreset_write(struct file *file, const char __user *data,
 
        ret = count;
 exit_unlock:
-       rtnl_unlock();
+       netdev_unlock(ns->netdev);
        return ret;
 }
 
index 7c6e0b5b6acb55f376ec725dfb71d1f70a4320c3..5c4d79a1bcd821cd39e985429f56bed76b8e92e1 100644 (file)
@@ -25,7 +25,6 @@
 
 /* Device memory support */
 
-/* Protected by rtnl_lock() */
 static DEFINE_XARRAY_FLAGS(net_devmem_dmabuf_bindings, XA_FLAGS_ALLOC1);
 
 static const struct memory_provider_ops dmabuf_devmem_ops;
@@ -128,9 +127,10 @@ void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
                rxq->mp_params.mp_priv = NULL;
                rxq->mp_params.mp_ops = NULL;
 
+               netdev_lock(binding->dev);
                rxq_idx = get_netdev_rx_queue_index(rxq);
-
                WARN_ON(netdev_rx_queue_restart(binding->dev, rxq_idx));
+               netdev_unlock(binding->dev);
        }
 
        xa_erase(&net_devmem_dmabuf_bindings, binding->id);
index 63e10717efc5e09d614b934eca79a7d9e3d6fc33..a186fea63c09e437f341e5eb29b2a8613a8972a9 100644 (file)
@@ -860,12 +860,11 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
        }
 
        mutex_lock(&priv->lock);
-       rtnl_lock();
 
-       netdev = __dev_get_by_index(genl_info_net(info), ifindex);
+       netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
        if (!netdev || !netif_device_present(netdev)) {
                err = -ENODEV;
-               goto err_unlock;
+               goto err_unlock_sock;
        }
 
        if (dev_xdp_prog_count(netdev)) {
@@ -918,7 +917,8 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto err_unbind;
 
-       rtnl_unlock();
+       netdev_unlock(netdev);
+
        mutex_unlock(&priv->lock);
 
        return 0;
@@ -926,7 +926,8 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
 err_unbind:
        net_devmem_unbind_dmabuf(binding);
 err_unlock:
-       rtnl_unlock();
+       netdev_unlock(netdev);
+err_unlock_sock:
        mutex_unlock(&priv->lock);
 err_genlmsg_free:
        nlmsg_free(rsp);
@@ -946,9 +947,7 @@ void netdev_nl_sock_priv_destroy(struct netdev_nl_sock *priv)
 
        mutex_lock(&priv->lock);
        list_for_each_entry_safe(binding, temp, &priv->bindings, list) {
-               rtnl_lock();
                net_devmem_unbind_dmabuf(binding);
-               rtnl_unlock();
        }
        mutex_unlock(&priv->lock);
 }
index 7419c41fd3cb93ab5b0d531ab463c61ba1b01909..a5b234b33cd5b93bcf05fc1316d444aa04155a59 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include <linux/netdevice.h>
+#include <net/netdev_lock.h>
 #include <net/netdev_queues.h>
 #include <net/netdev_rx_queue.h>
 #include <net/page_pool/memory_provider.h>
@@ -18,7 +19,7 @@ int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx)
            !qops->ndo_queue_mem_alloc || !qops->ndo_queue_start)
                return -EOPNOTSUPP;
 
-       ASSERT_RTNL();
+       netdev_assert_locked(dev);
 
        new_mem = kvzalloc(qops->ndo_queue_mem_size, GFP_KERNEL);
        if (!new_mem)
@@ -30,8 +31,6 @@ int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx)
                goto err_free_new_mem;
        }
 
-       netdev_lock(dev);
-
        err = qops->ndo_queue_mem_alloc(dev, new_mem, rxq_idx);
        if (err)
                goto err_free_old_mem;
@@ -54,8 +53,6 @@ int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx)
 
        qops->ndo_queue_mem_free(dev, old_mem);
 
-       netdev_unlock(dev);
-
        kvfree(old_mem);
        kvfree(new_mem);
 
@@ -80,7 +77,6 @@ err_free_new_queue_mem:
        qops->ndo_queue_mem_free(dev, new_mem);
 
 err_free_old_mem:
-       netdev_unlock(dev);
        kvfree(old_mem);
 
 err_free_new_mem:
@@ -118,9 +114,9 @@ int net_mp_open_rxq(struct net_device *dev, unsigned ifq_idx,
 {
        int ret;
 
-       rtnl_lock();
+       netdev_lock(dev);
        ret = __net_mp_open_rxq(dev, ifq_idx, p);
-       rtnl_unlock();
+       netdev_unlock(dev);
        return ret;
 }
 
@@ -153,7 +149,7 @@ static void __net_mp_close_rxq(struct net_device *dev, unsigned ifq_idx,
 void net_mp_close_rxq(struct net_device *dev, unsigned ifq_idx,
                      struct pp_memory_provider_params *old_p)
 {
-       rtnl_lock();
+       netdev_lock(dev);
        __net_mp_close_rxq(dev, ifq_idx, old_p);
-       rtnl_unlock();
+       netdev_unlock(dev);
 }