From: Johannes Berg 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. Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 46b72f3b5ea4..bf64cafa02fc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3794,8 +3794,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; } @@ -3804,6 +3806,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; @@ -3818,18 +3821,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; @@ -3871,7 +3874,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--; @@ -3881,7 +3884,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; @@ -4857,7 +4860,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, @@ -4920,7 +4923,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; } -- 2.56.0