From 6681721a1fc4cb2625350fb5f86915cd67bd3bef Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Apr 20 2023 11:00:48 +0000 Subject: wifi: iwlwifi: mvm: fix mvmtxq->stopped handling (bsc#1012628). --- diff --git a/patches.kernel.org/6.2.12-094-wifi-iwlwifi-mvm-fix-mvmtxq-stopped-handling.patch b/patches.kernel.org/6.2.12-094-wifi-iwlwifi-mvm-fix-mvmtxq-stopped-handling.patch new file mode 100644 index 0000000..2b9b634 --- /dev/null +++ b/patches.kernel.org/6.2.12-094-wifi-iwlwifi-mvm-fix-mvmtxq-stopped-handling.patch @@ -0,0 +1,98 @@ +From: Johannes Berg +Date: Fri, 17 Mar 2023 10:53:24 +0100 +Subject: [PATCH] wifi: iwlwifi: mvm: fix mvmtxq->stopped handling +References: bsc#1012628 +Patch-mainline: 6.2.12 +Git-commit: b58e3d4311b54b6dd0e37165277965da0c9eb21d + +[ Upstream commit b58e3d4311b54b6dd0e37165277965da0c9eb21d ] + +This could race if the queue is redirected while full, then +the flushing internally would start it while it's not yet +usable again. Fix it by using two state bits instead of just +one. + +Reviewed-by: Benjamin Berg +Tested-by: Jose Ignacio Tornos Martinez +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +Signed-off-by: Jiri Slaby +--- + drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 ++++- + drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 4 +++- + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 ++++- + drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 4 ++-- + 4 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +index 5273ade7..5b497418 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +@@ -732,7 +732,10 @@ void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq) + + rcu_read_lock(); + do { +- while (likely(!mvmtxq->stopped && ++ while (likely(!test_bit(IWL_MVM_TXQ_STATE_STOP_FULL, ++ &mvmtxq->state) && ++ !test_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT, ++ &mvmtxq->state) && + !test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status))) { + skb = ieee80211_tx_dequeue(hw, txq); + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +index ce6b701f..3146b3d0 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +@@ -729,7 +729,9 @@ struct iwl_mvm_txq { + struct list_head list; + u16 txq_id; + atomic_t tx_request; +- bool stopped; ++#define IWL_MVM_TXQ_STATE_STOP_FULL 0 ++#define IWL_MVM_TXQ_STATE_STOP_REDIRECT 1 ++ unsigned long state; + }; + + static inline struct iwl_mvm_txq * +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +index ebe6d9c4..f43e617f 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +@@ -1690,7 +1690,10 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode, + + txq = sta->txq[tid]; + mvmtxq = iwl_mvm_txq_from_mac80211(txq); +- mvmtxq->stopped = !start; ++ if (start) ++ clear_bit(IWL_MVM_TXQ_STATE_STOP_FULL, &mvmtxq->state); ++ else ++ set_bit(IWL_MVM_TXQ_STATE_STOP_FULL, &mvmtxq->state); + + if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST) + iwl_mvm_mac_itxq_xmit(mvm->hw, txq); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +index 69634fb8..21ad7b85 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +@@ -693,7 +693,7 @@ static int iwl_mvm_redirect_queue(struct iwl_mvm *mvm, int queue, int tid, + queue, iwl_mvm_ac_to_tx_fifo[ac]); + + /* Stop the queue and wait for it to empty */ +- txq->stopped = true; ++ set_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT, &txq->state); + + ret = iwl_trans_wait_tx_queues_empty(mvm->trans, BIT(queue)); + if (ret) { +@@ -736,7 +736,7 @@ static int iwl_mvm_redirect_queue(struct iwl_mvm *mvm, int queue, int tid, + + out: + /* Continue using the queue */ +- txq->stopped = false; ++ clear_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT, &txq->state); + + return ret; + } +-- +2.35.3 + diff --git a/series.conf b/series.conf index 1f84628..beb8d7a 100644 --- a/series.conf +++ b/series.conf @@ -2321,6 +2321,7 @@ patches.kernel.org/6.2.12-091-verify_pefile-relax-wrapper-length-check.patch patches.kernel.org/6.2.12-092-asymmetric_keys-log-on-fatal-failures-in-PE-pk.patch patches.kernel.org/6.2.12-093-nvme-send-Identify-with-CNS-06h-only-to-I-O-co.patch + patches.kernel.org/6.2.12-094-wifi-iwlwifi-mvm-fix-mvmtxq-stopped-handling.patch ######################################################## # Build fixes that apply to the vanilla kernel too.