summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2024-12-28 22:34:18 +0200
committerJohannes Berg <johannes.berg@intel.com>2025-01-13 15:26:41 +0100
commitc866a9852398fe74f3db14154e667fa8eb6da082 (patch)
tree07d8c99441d89bbfcb6f3dcbb151f991177e941b
parent9e28fcabce7070ab73782dea1452fee871f562a0 (diff)
wifi: iwlwifi: mvm: fix add stream vs. restart race
My recent restart related work has made this race more likely to happen and we've now noticed it, but it seems that it was always possible. The race is that the add stream work can be scheduled just before a restart is scheduled and then execute before the restart, accessing the device while it's doing the restart and not accessible. To fix this, check if the device is restarting and abort the work in that case. Reschedule it after the restart as well. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20241228223206.9c30af039b4d.I1a32936776f8ba5e83dda0a68ffc2722d9d37950@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c9
2 files changed, 10 insertions, 3 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 3e0f34dc6e1a..a5b4f1b843c0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1341,6 +1341,10 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
IWL_INFO(mvm, "restart completed\n");
iwl_trans_finish_sw_reset(mvm->trans);
+
+ /* no need to lock, adding in parallel would schedule too */
+ if (!list_empty(&mvm->add_stream_txqs))
+ schedule_work(&mvm->add_stream_wk);
}
void iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 9d9d385f67ac..735a66269f88 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1520,7 +1520,12 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk)
struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm,
add_stream_wk);
- mutex_lock(&mvm->mutex);
+ guard(mvm)(mvm);
+
+ /* will reschedule to run after restart */
+ if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) ||
+ test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
+ return;
iwl_mvm_inactivity_check(mvm, IWL_INVALID_STA);
@@ -1564,8 +1569,6 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk)
iwl_mvm_mac_itxq_xmit(mvm->hw, txq);
local_bh_enable();
}
-
- mutex_unlock(&mvm->mutex);
}
static int iwl_mvm_reserve_sta_stream(struct iwl_mvm *mvm,