Skip to content

Commit b58e3d4

Browse files
committed
wifi: iwlwifi: mvm: fix mvmtxq->stopped handling
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 <[email protected]> Tested-by: Jose Ignacio Tornos Martinez <[email protected]> Signed-off-by: Johannes Berg <[email protected]>
1 parent 007ae9b commit b58e3d4

File tree

4 files changed

+13
-5
lines changed

4 files changed

+13
-5
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,10 @@ void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
732732

733733
rcu_read_lock();
734734
do {
735-
while (likely(!mvmtxq->stopped &&
735+
while (likely(!test_bit(IWL_MVM_TXQ_STATE_STOP_FULL,
736+
&mvmtxq->state) &&
737+
!test_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT,
738+
&mvmtxq->state) &&
736739
!test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status))) {
737740
skb = ieee80211_tx_dequeue(hw, txq);
738741

drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,9 @@ struct iwl_mvm_txq {
729729
struct list_head list;
730730
u16 txq_id;
731731
atomic_t tx_request;
732-
bool stopped;
732+
#define IWL_MVM_TXQ_STATE_STOP_FULL 0
733+
#define IWL_MVM_TXQ_STATE_STOP_REDIRECT 1
734+
unsigned long state;
733735
};
734736

735737
static inline struct iwl_mvm_txq *

drivers/net/wireless/intel/iwlwifi/mvm/ops.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,10 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode,
16911691

16921692
txq = sta->txq[tid];
16931693
mvmtxq = iwl_mvm_txq_from_mac80211(txq);
1694-
mvmtxq->stopped = !start;
1694+
if (start)
1695+
clear_bit(IWL_MVM_TXQ_STATE_STOP_FULL, &mvmtxq->state);
1696+
else
1697+
set_bit(IWL_MVM_TXQ_STATE_STOP_FULL, &mvmtxq->state);
16951698

16961699
if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST)
16971700
iwl_mvm_mac_itxq_xmit(mvm->hw, txq);

drivers/net/wireless/intel/iwlwifi/mvm/sta.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ static int iwl_mvm_redirect_queue(struct iwl_mvm *mvm, int queue, int tid,
693693
queue, iwl_mvm_ac_to_tx_fifo[ac]);
694694

695695
/* Stop the queue and wait for it to empty */
696-
txq->stopped = true;
696+
set_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT, &txq->state);
697697

698698
ret = iwl_trans_wait_tx_queues_empty(mvm->trans, BIT(queue));
699699
if (ret) {
@@ -736,7 +736,7 @@ static int iwl_mvm_redirect_queue(struct iwl_mvm *mvm, int queue, int tid,
736736

737737
out:
738738
/* Continue using the queue */
739-
txq->stopped = false;
739+
clear_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT, &txq->state);
740740

741741
return ret;
742742
}

0 commit comments

Comments
 (0)