wifi: cfg80211: hold wiphy lock when sending wiphy
Sending the wiphy out might cause calls to the driver, notably get_txq_stats() and get_antenna(). These aren't very important, since the normally have their own locks and/or just send out static data, but if the contract should be that the wiphy lock is always held, these are also affected. Fix that. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
7d2d0ff49d
commit
4d45145ba6
|
@ -129,6 +129,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
|
|||
int result;
|
||||
|
||||
ASSERT_RTNL();
|
||||
lockdep_assert_wiphy(&rdev->wiphy);
|
||||
|
||||
/* Ignore nop renames */
|
||||
if (strcmp(newname, wiphy_name(&rdev->wiphy)) == 0)
|
||||
|
@ -195,6 +196,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
|
|||
continue;
|
||||
nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE);
|
||||
}
|
||||
|
||||
wiphy_lock(&rdev->wiphy);
|
||||
nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
|
||||
|
||||
wiphy_net_set(&rdev->wiphy, net);
|
||||
|
@ -203,6 +206,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
|
|||
WARN_ON(err);
|
||||
|
||||
nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
if (!wdev->netdev)
|
||||
continue;
|
||||
|
@ -941,8 +946,10 @@ int wiphy_register(struct wiphy *wiphy)
|
|||
rdev->wiphy.features |= NL80211_FEATURE_SCAN_FLUSH;
|
||||
|
||||
rtnl_lock();
|
||||
wiphy_lock(&rdev->wiphy);
|
||||
res = device_add(&rdev->wiphy.dev);
|
||||
if (res) {
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
rtnl_unlock();
|
||||
return res;
|
||||
}
|
||||
|
@ -956,6 +963,7 @@ int wiphy_register(struct wiphy *wiphy)
|
|||
|
||||
cfg80211_debugfs_rdev_add(rdev);
|
||||
nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
|
||||
/* set up regulatory info */
|
||||
wiphy_regulatory_register(wiphy);
|
||||
|
|
|
@ -3081,6 +3081,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
if (state->filter_wiphy != -1 &&
|
||||
state->filter_wiphy != rdev->wiphy_idx)
|
||||
continue;
|
||||
wiphy_lock(&rdev->wiphy);
|
||||
/* attempt to fit multiple wiphy data chunks into the skb */
|
||||
do {
|
||||
ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
|
||||
|
@ -3107,6 +3108,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
cb->min_dump_alloc < 4096) {
|
||||
cb->min_dump_alloc = 4096;
|
||||
state->split_start = 0;
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
rtnl_unlock();
|
||||
return 1;
|
||||
}
|
||||
|
@ -3114,6 +3116,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
break;
|
||||
}
|
||||
} while (state->split_start > 0);
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
break;
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
|
Loading…
Reference in New Issue