]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: ethtool: optionally skip rtnl_lock in RSS context handlers
authorJakub Kicinski <kuba@kernel.org>
Fri, 5 Jun 2026 00:29:09 +0000 (17:29 -0700)
committerJakub Kicinski <kuba@kernel.org>
Tue, 9 Jun 2026 17:13:05 +0000 (10:13 -0700)
Skip rtnl_lock in RSS context handlers if device is ops-locked.
Fairly trivial conversion. bnxt needed rtnl_lock for changing
the main context but looks like additional contexts are fine
without it.

Note (for review bots?) that ethnl_ops_begin() checks whether
the device is still registered.

Reviewed-by: Eric Dumazet <edumazet@google.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20260605002912.3456868-10-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ethtool/rss.c

index 65bad23d5c599eca1795de22321210f1754f2cd5..d8adc78e3775a0394543f5881f592e6a6ee95b4e 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <net/netdev_lock.h>
 
+#include "../core/dev.h"
 #include "common.h"
 #include "netlink.h"
 
@@ -468,21 +469,16 @@ int ethnl_rss_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 {
        struct rss_nl_dump_ctx *ctx = rss_dump_ctx(cb);
        struct net *net = sock_net(skb->sk);
-       struct net_device *dev;
        int ret = 0;
 
-       rtnl_lock();
-       for_each_netdev_dump(net, dev, ctx->ifindex) {
+       for_each_netdev_lock_ops_compat_scoped(net, dev, ctx->ifindex) {
                if (ctx->match_ifindex && ctx->match_ifindex != ctx->ifindex)
                        break;
 
-               netdev_lock_ops(dev);
                ret = rss_dump_one_dev(skb, cb, dev);
-               netdev_unlock_ops(dev);
                if (ret)
                        break;
        }
-       rtnl_unlock();
 
        return ret;
 }
@@ -1037,8 +1033,7 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
        if (ret)
                goto exit_free_dev;
 
-       rtnl_lock();
-       netdev_lock_ops(dev);
+       netdev_lock_ops_compat(dev);
 
        ret = ethnl_ops_begin(dev);
        if (ret < 0)
@@ -1125,8 +1120,7 @@ exit_clean_data:
 exit_ops:
        ethnl_ops_complete(dev);
 exit_dev_unlock:
-       netdev_unlock_ops(dev);
-       rtnl_unlock();
+       netdev_unlock_ops_compat(dev);
 exit_free_dev:
        ethnl_parse_header_dev_put(&req.base);
 exit_free_rsp:
@@ -1179,8 +1173,7 @@ int ethnl_rss_delete_doit(struct sk_buff *skb, struct genl_info *info)
                goto exit_free_dev;
        }
 
-       rtnl_lock();
-       netdev_lock_ops(dev);
+       netdev_lock_ops_compat(dev);
 
        ret = ethnl_ops_begin(dev);
        if (ret < 0)
@@ -1210,8 +1203,7 @@ exit_unlock:
        mutex_unlock(&dev->ethtool->rss_lock);
        ethnl_ops_complete(dev);
 exit_dev_unlock:
-       netdev_unlock_ops(dev);
-       rtnl_unlock();
+       netdev_unlock_ops_compat(dev);
 exit_free_dev:
        ethnl_parse_header_dev_put(&req);
        return ret;