wifi: nl80211: avoid RTNL for wiphy/interface netlink dumps

The wiphy/interface netlink dumps only need the RTNL for
the list and, possibly, filtering by netdev. This can be
easily replaced now, do that.

Link: https://patch.msgid.link/20261011113308.d2b68635eeec.I42540f72c38c1bbb6edd2396d6dcc6199f1bc8c0@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2026-10-11 11:31:28 +02:00
parent 9a8407984a
commit 65460860e1

View File

@ -3867,8 +3867,10 @@ static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
struct cfg80211_registered_device *rdev;
int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
rcu_read_lock();
netdev = dev_get_by_index_rcu(sock_net(skb->sk), ifidx);
if (!netdev) {
rcu_read_unlock();
ret = -ENODEV;
goto out;
}
@ -3877,6 +3879,7 @@ static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
netdev->ieee80211_ptr->wiphy);
state->filter_wiphy = rdev->wiphy_idx;
}
rcu_read_unlock();
}
ret = 0;
@ -3891,18 +3894,18 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
struct cfg80211_registered_device *rdev;
rtnl_lock();
mutex_lock(&cfg80211_mutex);
if (!state) {
state = kzalloc_obj(*state);
if (!state) {
rtnl_unlock();
mutex_unlock(&cfg80211_mutex);
return -ENOMEM;
}
state->filter_wiphy = -1;
ret = nl80211_dump_wiphy_parse(skb, cb, state);
if (ret) {
kfree(state);
rtnl_unlock();
mutex_unlock(&cfg80211_mutex);
return ret;
}
cb->args[0] = (long)state;
@ -3944,7 +3947,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
cb->min_dump_alloc = 4096;
state->split_start = 0;
wiphy_unlock(&rdev->wiphy);
rtnl_unlock();
mutex_unlock(&cfg80211_mutex);
return 1;
}
idx--;
@ -3954,7 +3957,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
wiphy_unlock(&rdev->wiphy);
break;
}
rtnl_unlock();
mutex_unlock(&cfg80211_mutex);
state->start = idx;
@ -4930,7 +4933,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
struct wireless_dev *wdev;
int ret;
rtnl_lock();
mutex_lock(&cfg80211_mutex);
if (!cb->args[2]) {
struct nl80211_dump_wiphy_state state = {
.filter_wiphy = -1,
@ -4993,7 +4996,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
ret = skb->len;
out_unlock:
rtnl_unlock();
mutex_unlock(&cfg80211_mutex);
return ret;
}