netdev: depend on netdev->lock for xdp features

Writes to XDP features are now protected by netdev->lock.
Other things we report are based on ops which don't change
once device has been registered. It is safe to stop taking
rtnl_lock, and depend on netdev->lock instead.

Reviewed-by: Joe Damato <jdamato@fastly.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250408195956.412733-7-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-04-08 12:59:53 -07:00
parent 03df156dd3
commit 99e44f39a8

View file

@ -38,6 +38,8 @@ netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
u64 xdp_rx_meta = 0; u64 xdp_rx_meta = 0;
void *hdr; void *hdr;
netdev_assert_locked(netdev); /* note: rtnl_lock may not be held! */
hdr = genlmsg_iput(rsp, info); hdr = genlmsg_iput(rsp, info);
if (!hdr) if (!hdr)
return -EMSGSIZE; return -EMSGSIZE;
@ -122,15 +124,14 @@ int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
if (!rsp) if (!rsp)
return -ENOMEM; return -ENOMEM;
rtnl_lock(); netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
if (!netdev) {
netdev = __dev_get_by_index(genl_info_net(info), ifindex);
if (netdev)
err = netdev_nl_dev_fill(netdev, rsp, info);
else
err = -ENODEV; err = -ENODEV;
goto err_free_msg;
}
rtnl_unlock(); err = netdev_nl_dev_fill(netdev, rsp, info);
netdev_unlock(netdev);
if (err) if (err)
goto err_free_msg; goto err_free_msg;
@ -146,18 +147,15 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{ {
struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb); struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
struct net_device *netdev; int err;
int err = 0;
rtnl_lock(); for_each_netdev_lock_scoped(net, netdev, ctx->ifindex) {
for_each_netdev_dump(net, netdev, ctx->ifindex) {
err = netdev_nl_dev_fill(netdev, skb, genl_info_dump(cb)); err = netdev_nl_dev_fill(netdev, skb, genl_info_dump(cb));
if (err < 0) if (err < 0)
break; return err;
} }
rtnl_unlock();
return err; return 0;
} }
static int static int