mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
wifi: mac80211: ibss: wait for in-flight TX on disconnect
While leaving an IBSS in ieee80211_ibss_disconnect() mac80211 flushes stations, turns the carrier off and immediately tells the driver to leave as well. While there may be synchronize_net() in station flush and in this code later, packets can still be transmitted due to cross-CPU race conditions after carrier off is set. Therefore, it's possible for a race to happen where a TX to the driver occurs while or after telling it to leave the IBSS. This can be confusing to drivers, and in the case of iwlwifi leads to an attempt to use invalid queues. Move netif_carrier_off() to occur before sta_info_flush() during IBSS disconnect, and add synchronize_net() if flushing didn't, so that the synchronize_net() always happens between turning the carrier off and telling the driver, avoiding this race. Signed-off-by: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20260706223751.da1ce439cc93.If5cf482f87ab98ce66dd48724e24c81fed236d3f@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
4e72459683
commit
d0e69d9afa
|
|
@ -668,7 +668,9 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
|
|||
|
||||
ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
|
||||
|
||||
sta_info_flush(sdata, -1);
|
||||
netif_carrier_off(sdata->dev);
|
||||
if (!sta_info_flush(sdata, -1))
|
||||
synchronize_net();
|
||||
|
||||
spin_lock_bh(&ifibss->incomplete_lock);
|
||||
while (!list_empty(&ifibss->incomplete_stations)) {
|
||||
|
|
@ -682,8 +684,6 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
|
|||
}
|
||||
spin_unlock_bh(&ifibss->incomplete_lock);
|
||||
|
||||
netif_carrier_off(sdata->dev);
|
||||
|
||||
sdata->vif.cfg.ibss_joined = false;
|
||||
sdata->vif.cfg.ibss_creator = false;
|
||||
sdata->vif.bss_conf.enable_beacon = false;
|
||||
|
|
@ -710,7 +710,6 @@ static void ieee80211_csa_connection_drop_work(struct wiphy *wiphy,
|
|||
u.ibss.csa_connection_drop_work);
|
||||
|
||||
ieee80211_ibss_disconnect(sdata);
|
||||
synchronize_rcu();
|
||||
skb_queue_purge(&sdata->skb_queue);
|
||||
|
||||
/* trigger a scan to find another IBSS network to join */
|
||||
|
|
@ -1797,8 +1796,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
|
|||
memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa));
|
||||
memset(&ifibss->ht_capa_mask, 0, sizeof(ifibss->ht_capa_mask));
|
||||
|
||||
synchronize_rcu();
|
||||
|
||||
skb_queue_purge(&sdata->skb_queue);
|
||||
|
||||
timer_delete_sync(&sdata->u.ibss.timer);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user