diff options
author | Johannes Berg <johannes.berg@intel.com> | 2015-07-17 13:39:38 (GMT) |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2015-07-17 13:39:41 (GMT) |
commit | 72bbe3d1c2d7a9e257956912040ffc7ba9f71e0d (patch) | |
tree | 8f014bc8663c3e0eec3250ceb46ca18674e8932a /net/mac80211/iface.c | |
parent | 322cd406da0b102dda9c0eec46181458a3667dbb (diff) | |
parent | 923b352f19d9ea971ae2536eab55f5fc9e95fedf (diff) | |
download | linux-72bbe3d1c2d7a9e257956912040ffc7ba9f71e0d.tar.xz |
Merge branch 'mac80211' into mac80211-next
This is necessary to merge the new TDLS and mesh patches,
as they depend on some fixes.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ed1edac..553ac6d 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1863,10 +1863,6 @@ void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata) ieee80211_teardown_sdata(sdata); } -/* - * Remove all interfaces, may only be called at hardware unregistration - * time because it doesn't do RCU-safe list removals. - */ void ieee80211_remove_interfaces(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata, *tmp; @@ -1875,14 +1871,21 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) ASSERT_RTNL(); - /* - * Close all AP_VLAN interfaces first, as otherwise they - * might be closed while the AP interface they belong to - * is closed, causing unregister_netdevice_many() to crash. + /* Before destroying the interfaces, make sure they're all stopped so + * that the hardware is stopped. Otherwise, the driver might still be + * iterating the interfaces during the shutdown, e.g. from a worker + * or from RX processing or similar, and if it does so (using atomic + * iteration) while we're manipulating the list, the iteration will + * crash. + * + * After this, the hardware should be stopped and the driver should + * have stopped all of its activities, so that we can do RCU-unaware + * manipulations of the interface list below. */ - list_for_each_entry(sdata, &local->interfaces, list) - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - dev_close(sdata->dev); + cfg80211_shutdown_all_interfaces(local->hw.wiphy); + + WARN(local->open_count, "%s: open count remains %d\n", + wiphy_name(local->hw.wiphy), local->open_count); mutex_lock(&local->iflist_mtx); list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { |