diff options
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 9ed49ad0380f..9cbebc2eb87f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -844,11 +844,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, * * sta_info_flush_cleanup() requires rcu_barrier() * first to wait for the station call_rcu() calls - * to complete, here we need at least sychronize_rcu() - * it to wait for the RX path in case it is using the + * to complete, and we also need synchronize_rcu() + * to wait for the RX path in case it is using the * interface and enqueuing frames at this very time on * another CPU. */ + synchronize_rcu(); rcu_barrier(); sta_info_flush_cleanup(sdata); @@ -1648,6 +1649,15 @@ 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. + */ + list_for_each_entry(sdata, &local->interfaces, list) + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + dev_close(sdata->dev); + mutex_lock(&local->iflist_mtx); list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { list_del(&sdata->list); |