wifi: mac80211: mlme: move disconnects to wiphy work

Move the beacon loss work that might cause a disconnect
and the CSA disconnect work to be wiphy work, so we hold
the wiphy lock for them.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2023-06-06 14:49:31 +02:00
parent 87351d0926
commit 4b8d43f113
4 changed files with 32 additions and 26 deletions

View file

@ -3590,7 +3590,7 @@ void ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif, bool block_t
sdata->deflink.csa_block_tx = block_tx;
sdata_info(sdata, "channel switch failed, disconnecting\n");
ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
wiphy_work_queue(local->hw.wiphy, &ifmgd->csa_connection_drop_work);
}
EXPORT_SYMBOL(ieee80211_channel_switch_disconnect);

View file

@ -466,8 +466,8 @@ struct ieee80211_if_managed {
struct timer_list conn_mon_timer;
struct timer_list bcn_mon_timer;
struct work_struct monitor_work;
struct work_struct beacon_connection_loss_work;
struct work_struct csa_connection_drop_work;
struct wiphy_work beacon_connection_loss_work;
struct wiphy_work csa_connection_drop_work;
unsigned long beacon_timeout;
unsigned long probe_timeout;

View file

@ -364,7 +364,8 @@ static void ieee80211_restart_work(struct work_struct *work)
* The exception is ieee80211_chswitch_done.
* Then we can have a race...
*/
cancel_work_sync(&sdata->u.mgd.csa_connection_drop_work);
wiphy_work_cancel(local->hw.wiphy,
&sdata->u.mgd.csa_connection_drop_work);
if (sdata->vif.bss_conf.csa_active) {
sdata_lock(sdata);
ieee80211_sta_connection_lost(sdata,

View file

@ -1724,8 +1724,8 @@ static void ieee80211_chswitch_work(struct wiphy *wiphy,
sdata_info(sdata,
"failed to use reserved channel context, disconnecting (err=%d)\n",
ret);
ieee80211_queue_work(&sdata->local->hw,
&ifmgd->csa_connection_drop_work);
wiphy_work_queue(sdata->local->hw.wiphy,
&ifmgd->csa_connection_drop_work);
goto out;
}
@ -1736,8 +1736,8 @@ static void ieee80211_chswitch_work(struct wiphy *wiphy,
&link->csa_chandef)) {
sdata_info(sdata,
"failed to finalize channel switch, disconnecting\n");
ieee80211_queue_work(&sdata->local->hw,
&ifmgd->csa_connection_drop_work);
wiphy_work_queue(sdata->local->hw.wiphy,
&ifmgd->csa_connection_drop_work);
goto out;
}
@ -1781,8 +1781,8 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_link_data *link)
if (ret) {
sdata_info(sdata,
"driver post channel switch failed, disconnecting\n");
ieee80211_queue_work(&local->hw,
&ifmgd->csa_connection_drop_work);
wiphy_work_queue(sdata->local->hw.wiphy,
&ifmgd->csa_connection_drop_work);
return;
}
@ -1801,8 +1801,8 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
if (!success) {
sdata_info(sdata,
"driver channel switch failed, disconnecting\n");
ieee80211_queue_work(&sdata->local->hw,
&ifmgd->csa_connection_drop_work);
wiphy_work_queue(sdata->local->hw.wiphy,
&ifmgd->csa_connection_drop_work);
} else {
wiphy_delayed_work_queue(sdata->local->hw.wiphy,
&sdata->deflink.u.mgd.chswitch_work,
@ -2018,7 +2018,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
link->conf->csa_active = true;
link->csa_block_tx = csa_ie.mode;
ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
wiphy_work_queue(sdata->local->hw.wiphy,
&ifmgd->csa_connection_drop_work);
mutex_unlock(&local->chanctx_mtx);
mutex_unlock(&local->mtx);
}
@ -3415,7 +3416,8 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
sdata_unlock(sdata);
}
static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
static void ieee80211_beacon_connection_loss_work(struct wiphy *wiphy,
struct wiphy_work *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data,
@ -3440,7 +3442,8 @@ static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
}
}
static void ieee80211_csa_connection_drop_work(struct work_struct *work)
static void ieee80211_csa_connection_drop_work(struct wiphy *wiphy,
struct wiphy_work *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data,
@ -3457,7 +3460,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
trace_api_beacon_loss(sdata);
sdata->u.mgd.connection_loss = false;
ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
wiphy_work_queue(hw->wiphy, &sdata->u.mgd.beacon_connection_loss_work);
}
EXPORT_SYMBOL(ieee80211_beacon_loss);
@ -3469,7 +3472,7 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif)
trace_api_connection_loss(sdata);
sdata->u.mgd.connection_loss = true;
ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
wiphy_work_queue(hw->wiphy, &sdata->u.mgd.beacon_connection_loss_work);
}
EXPORT_SYMBOL(ieee80211_connection_loss);
@ -3485,7 +3488,7 @@ void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect)
sdata->u.mgd.driver_disconnect = true;
sdata->u.mgd.reconnect = reconnect;
ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
wiphy_work_queue(hw->wiphy, &sdata->u.mgd.beacon_connection_loss_work);
}
EXPORT_SYMBOL(ieee80211_disconnect);
@ -6374,8 +6377,8 @@ static void ieee80211_sta_bcn_mon_timer(struct timer_list *t)
return;
sdata->u.mgd.connection_loss = false;
ieee80211_queue_work(&sdata->local->hw,
&sdata->u.mgd.beacon_connection_loss_work);
wiphy_work_queue(sdata->local->hw.wiphy,
&sdata->u.mgd.beacon_connection_loss_work);
}
static void ieee80211_sta_conn_mon_timer(struct timer_list *t)
@ -6550,10 +6553,10 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
INIT_WORK(&ifmgd->beacon_connection_loss_work,
ieee80211_beacon_connection_loss_work);
INIT_WORK(&ifmgd->csa_connection_drop_work,
ieee80211_csa_connection_drop_work);
wiphy_work_init(&ifmgd->beacon_connection_loss_work,
ieee80211_beacon_connection_loss_work);
wiphy_work_init(&ifmgd->csa_connection_drop_work,
ieee80211_csa_connection_drop_work);
INIT_DELAYED_WORK(&ifmgd->tdls_peer_del_work,
ieee80211_tdls_peer_del_work);
timer_setup(&ifmgd->timer, ieee80211_sta_timer, 0);
@ -7562,8 +7565,10 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
* cancelled when disconnecting.
*/
cancel_work_sync(&ifmgd->monitor_work);
cancel_work_sync(&ifmgd->beacon_connection_loss_work);
cancel_work_sync(&ifmgd->csa_connection_drop_work);
wiphy_work_cancel(sdata->local->hw.wiphy,
&ifmgd->beacon_connection_loss_work);
wiphy_work_cancel(sdata->local->hw.wiphy,
&ifmgd->csa_connection_drop_work);
cancel_delayed_work_sync(&ifmgd->tdls_peer_del_work);
sdata_lock(sdata);