netdev: don't hold rtnl_lock over nl queue info get when possible
authorJakub Kicinski <kuba@kernel.org>
Tue, 8 Apr 2025 19:59:51 +0000 (12:59 -0700)
committerJakub Kicinski <kuba@kernel.org>
Thu, 10 Apr 2025 00:01:52 +0000 (17:01 -0700)
Netdev queue dump accesses: NAPI, memory providers, XSk pointers.
All three are "ops protected" now, switch to the op compat locking.
rtnl lock does not have to be taken for "ops locked" devices.

Reviewed-by: Joe Damato <jdamato@fastly.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250408195956.412733-5-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/netdev-genl.c

index 5d7af50fe7027273881f4b0e384145b9d77168be..7ef9b019193644e96975fe2f1076919abbce6f7d 100644 (file)
@@ -481,18 +481,15 @@ int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info)
        if (!rsp)
                return -ENOMEM;
 
-       rtnl_lock();
-
-       netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
+       netdev = netdev_get_by_index_lock_ops_compat(genl_info_net(info),
+                                                    ifindex);
        if (netdev) {
                err = netdev_nl_queue_fill(rsp, netdev, q_id, q_type, info);
-               netdev_unlock(netdev);
+               netdev_unlock_ops_compat(netdev);
        } else {
                err = -ENODEV;
        }
 
-       rtnl_unlock();
-
        if (err)
                goto err_free_msg;
 
@@ -541,17 +538,17 @@ int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
        if (info->attrs[NETDEV_A_QUEUE_IFINDEX])
                ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
 
-       rtnl_lock();
        if (ifindex) {
-               netdev = netdev_get_by_index_lock(net, ifindex);
+               netdev = netdev_get_by_index_lock_ops_compat(net, ifindex);
                if (netdev) {
                        err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
-                       netdev_unlock(netdev);
+                       netdev_unlock_ops_compat(netdev);
                } else {
                        err = -ENODEV;
                }
        } else {
-               for_each_netdev_lock_scoped(net, netdev, ctx->ifindex) {
+               for_each_netdev_lock_ops_compat_scoped(net, netdev,
+                                                      ctx->ifindex) {
                        err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
                        if (err < 0)
                                break;
@@ -559,7 +556,6 @@ int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
                        ctx->txq_idx = 0;
                }
        }
-       rtnl_unlock();
 
        return err;
 }