Skip to content

Commit

Permalink
iwlwifi: mvm: don't schedule the roc_done_wk if it is already running
Browse files Browse the repository at this point in the history
[ Upstream commit a76b573 ]

When P2P roc is removed, the IWL_MVM_STATUS_NEED_FLUSH_P2P bit is set
to indicate to iwl_mvm_roc_done_wk() that the removed roc is a P2P
one, so it will flush the broadcast station and not the aux station.

However, since setting this bit and scheduling the worker is done
in roc ended flow as well as in case the roc is removed, there is
a race where the worker has already started running (but did not
test this bit yet) and then it is scheduled again. In this case,
the first run of the worker will clear this bit, and thus the second
run will find it already cleared and will try to flush and remove
the aux station by mistake.

Fix it by scheduling the worker only if this bit is not yet set. In
case this bit is already set, the worker is either running or
scheduled, so there is no need to re-schedule it.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210819183728.8c147659b331.If5924375e9bfd46214ab8ab81cb9d0f5c82fbcbc@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
AviStern authored and gregkh committed Sep 18, 2021
1 parent 536c99f commit 81f63f2
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
Expand Up @@ -246,6 +246,18 @@ static void iwl_mvm_te_check_trigger(struct iwl_mvm *mvm,
}
}

static void iwl_mvm_p2p_roc_finished(struct iwl_mvm *mvm)
{
/*
* If the IWL_MVM_STATUS_NEED_FLUSH_P2P is already set, then the
* roc_done_wk is already scheduled or running, so don't schedule it
* again to avoid a race where the roc_done_wk clears this bit after
* it is set here, affecting the next run of the roc_done_wk.
*/
if (!test_and_set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status))
iwl_mvm_roc_finished(mvm);
}

/*
* Handles a FW notification for an event that is known to the driver.
*
Expand Down Expand Up @@ -297,8 +309,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
switch (te_data->vif->type) {
case NL80211_IFTYPE_P2P_DEVICE:
ieee80211_remain_on_channel_expired(mvm->hw);
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
iwl_mvm_roc_finished(mvm);
iwl_mvm_p2p_roc_finished(mvm);
break;
case NL80211_IFTYPE_STATION:
/*
Expand Down Expand Up @@ -674,8 +685,7 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
/* Session protection is still ongoing. Cancel it */
iwl_mvm_cancel_session_protection(mvm, mvmvif, id);
if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
iwl_mvm_roc_finished(mvm);
iwl_mvm_p2p_roc_finished(mvm);
}
}
return false;
Expand Down Expand Up @@ -842,8 +852,7 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
/* End TE, notify mac80211 */
mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID;
ieee80211_remain_on_channel_expired(mvm->hw);
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
iwl_mvm_roc_finished(mvm);
iwl_mvm_p2p_roc_finished(mvm);
} else if (le32_to_cpu(notif->start)) {
if (WARN_ON(mvmvif->time_event_data.id !=
le32_to_cpu(notif->conf_id)))
Expand Down Expand Up @@ -1004,14 +1013,13 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
iwl_mvm_cancel_session_protection(mvm, mvmvif,
mvmvif->time_event_data.id);
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
iwl_mvm_p2p_roc_finished(mvm);
} else {
iwl_mvm_remove_aux_roc_te(mvm, mvmvif,
&mvmvif->time_event_data);
iwl_mvm_roc_finished(mvm);
}

iwl_mvm_roc_finished(mvm);

return;
}

Expand All @@ -1025,12 +1033,11 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)

if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
iwl_mvm_p2p_roc_finished(mvm);
} else {
iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data);
iwl_mvm_roc_finished(mvm);
}

iwl_mvm_roc_finished(mvm);
}

void iwl_mvm_remove_csa_period(struct iwl_mvm *mvm,
Expand Down

0 comments on commit 81f63f2

Please sign in to comment.