diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2015-08-13 14:42:55 +0200 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2015-08-13 14:42:55 +0200 |
commit | 5f6f02cd49d61e9856ff2c337578316a1a1b3f88 (patch) | |
tree | fd2e6961e8f609af41dd4a282008e1bc52cfa7c7 /net/mac80211/iface.c | |
parent | gpio: brcmstb: support wakeup from S5 cold boot (diff) | |
parent | Linux 4.2-rc4 (diff) | |
download | linux-5f6f02cd49d61e9856ff2c337578316a1a1b3f88.tar.xz linux-5f6f02cd49d61e9856ff2c337578316a1a1b3f88.zip |
Merge tag 'v4.2-rc4' into devel
Linux 4.2-rc4
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 ed1edac14372..553ac6dd4867 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) { |