This time, only RTNL locking reduction fallout.
- cfg80211_dev_rename() requires RTNL - cfg80211_change_iface() and cfg80211_set_encryption() require wiphy mutex (was missing in wireless extensions) - cfg80211_destroy_ifaces() requires wiphy mutex - netdev registration can fail due to notifiers, and then notifiers are "unrolled", need to handle this properly -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAmAZZAoACgkQB8qZga/f l8QW4A/+NSpqm/MMuw9IUwRsZ3wJUYI2SDj7xhbfpFEdNAmm7RjJLxF8NqCzFtqo 2XM9DzGkbvQKlPi4DmahnRVycFqlqTGkDDs5WOvg9NdL8/zygDLsTMWJsvyI6XEp 4Y8qLuwJpoaxDhmtEpjBNbQiZrXDdYptMRsvWpaLiLN8nlzWim+Sm+qiMeIWpxz2 axutgbyfO4pREU3wxRbxe2V0RNLxRqJ7g10siAkchP+NoK2SjM1tQKzyuN7ruImZ cVriA+j1u43rWseedoKZzofCvgd74nZAi87u8dpk673s7V71//8uTHhpIOBYUbfp 6mn1V2QhjiLZ3UZfdQFFQ+WjoowSEPMQ6gPe0EdPlWTYVNRWcQXzjIlznooZnxrE KVWYDYxkQKMgqrTFdUjcjOza9m4DG0aAJqqSQZ3r9KsRftseLM680vZY6AoteOOM WeaEt3p1Qaza18CA3BH1wVHmbNnwIfCiHtmsAefkgTD3cVH28IIUyGk4RsFPGWi0 APNNQOyiPPQCVnDAMZjhrKPMX2NTyWw5UziFhPPc2jo00XjPW0+mPRjiSO2W55kz ixui/foUN5um3kEc9wJgh62eLYjOAtBomKCNZEZQjJpS9VtsvyoaY/ZjK69lP3wQ XERj8D+fVpm8Hidbv7tb2gElJvra0X4ZCky2KixnICjCrwDBBzw= =bgnR -----END PGP SIGNATURE----- Merge tag 'mac80211-next-for-net-next-2021-02-02' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next Johannes Berg says: ==================== This time, only RTNL locking reduction fallout. - cfg80211_dev_rename() requires RTNL - cfg80211_change_iface() and cfg80211_set_encryption() require wiphy mutex (was missing in wireless extensions) - cfg80211_destroy_ifaces() requires wiphy mutex - netdev registration can fail due to notifiers, and then notifiers are "unrolled", need to handle this properly * tag 'mac80211-next-for-net-next-2021-02-02' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next: cfg80211: fix netdev registration deadlock cfg80211: call cfg80211_destroy_ifaces() with wiphy lock held wext: call cfg80211_set_encryption() with wiphy lock held wext: call cfg80211_change_iface() with wiphy lock held nl80211: call cfg80211_dev_rename() under RTNL ==================== Link: https://lore.kernel.org/r/20210202144106.38207-1-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
0256317a61
|
@ -5299,6 +5299,8 @@ static inline void wiphy_unlock(struct wiphy *wiphy)
|
|||
* @wiphy: pointer to hardware description
|
||||
* @iftype: interface type
|
||||
* @registered: is this wdev already registered with cfg80211
|
||||
* @registering: indicates we're doing registration under wiphy lock
|
||||
* for the notifier
|
||||
* @list: (private) Used to collect the interfaces
|
||||
* @netdev: (private) Used to reference back to the netdev, may be %NULL
|
||||
* @identifier: (private) Identifier used in nl80211 to identify this
|
||||
|
@ -5382,7 +5384,7 @@ struct wireless_dev {
|
|||
|
||||
struct mutex mtx;
|
||||
|
||||
bool use_4addr, is_running, registered;
|
||||
bool use_4addr, is_running, registered, registering;
|
||||
|
||||
u8 address[ETH_ALEN] __aligned(sizeof(u16));
|
||||
|
||||
|
|
|
@ -334,6 +334,7 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
|
|||
struct wireless_dev *wdev, *tmp;
|
||||
|
||||
ASSERT_RTNL();
|
||||
lockdep_assert_wiphy(&rdev->wiphy);
|
||||
|
||||
list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
|
||||
if (wdev->nl_owner_dead)
|
||||
|
@ -349,7 +350,9 @@ static void cfg80211_destroy_iface_wk(struct work_struct *work)
|
|||
destroy_work);
|
||||
|
||||
rtnl_lock();
|
||||
wiphy_lock(&rdev->wiphy);
|
||||
cfg80211_destroy_ifaces(rdev);
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
|
@ -1343,6 +1346,7 @@ int cfg80211_register_netdevice(struct net_device *dev)
|
|||
|
||||
/* we'll take care of this */
|
||||
wdev->registered = true;
|
||||
wdev->registering = true;
|
||||
ret = register_netdevice(dev);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
@ -1358,6 +1362,7 @@ int cfg80211_register_netdevice(struct net_device *dev)
|
|||
cfg80211_register_wdev(rdev, wdev);
|
||||
ret = 0;
|
||||
out:
|
||||
wdev->registering = false;
|
||||
if (ret)
|
||||
wdev->registered = false;
|
||||
return ret;
|
||||
|
@ -1400,7 +1405,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
|||
* It is possible to get NETDEV_UNREGISTER multiple times,
|
||||
* so check wdev->registered.
|
||||
*/
|
||||
if (wdev->registered) {
|
||||
if (wdev->registered && !wdev->registering) {
|
||||
wiphy_lock(&rdev->wiphy);
|
||||
_cfg80211_unregister_wdev(wdev, false);
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
|
|
|
@ -3220,7 +3220,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
|||
wdev = netdev->ieee80211_ptr;
|
||||
|
||||
wiphy_lock(&rdev->wiphy);
|
||||
rtnl_unlock();
|
||||
|
||||
/*
|
||||
* end workaround code, by now the rdev is available
|
||||
|
@ -3230,6 +3229,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[NL80211_ATTR_WIPHY_NAME])
|
||||
result = cfg80211_dev_rename(
|
||||
rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
|
||||
rtnl_unlock();
|
||||
|
||||
if (result)
|
||||
goto out;
|
||||
|
|
|
@ -39,6 +39,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
|
|||
struct cfg80211_registered_device *rdev;
|
||||
struct vif_params vifparams;
|
||||
enum nl80211_iftype type;
|
||||
int ret;
|
||||
|
||||
rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
|
||||
|
@ -61,7 +62,11 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
|
|||
|
||||
memset(&vifparams, 0, sizeof(vifparams));
|
||||
|
||||
return cfg80211_change_iface(rdev, dev, type, &vifparams);
|
||||
wiphy_lock(wdev->wiphy);
|
||||
ret = cfg80211_change_iface(rdev, dev, type, &vifparams);
|
||||
wiphy_unlock(wdev->wiphy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);
|
||||
|
||||
|
@ -650,6 +655,7 @@ static int cfg80211_wext_siwencodeext(struct net_device *dev,
|
|||
bool remove = false;
|
||||
struct key_params params;
|
||||
u32 cipher;
|
||||
int ret;
|
||||
|
||||
if (wdev->iftype != NL80211_IFTYPE_STATION &&
|
||||
wdev->iftype != NL80211_IFTYPE_ADHOC)
|
||||
|
@ -721,12 +727,16 @@ static int cfg80211_wext_siwencodeext(struct net_device *dev,
|
|||
params.seq_len = 6;
|
||||
}
|
||||
|
||||
return cfg80211_set_encryption(
|
||||
wiphy_lock(wdev->wiphy);
|
||||
ret = cfg80211_set_encryption(
|
||||
rdev, dev,
|
||||
!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
|
||||
addr, remove,
|
||||
ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
|
||||
idx, ¶ms);
|
||||
wiphy_unlock(wdev->wiphy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cfg80211_wext_giwencode(struct net_device *dev,
|
||||
|
|
Loading…
Reference in New Issue