提交 b967613d 编写于 作者: E Emmanuel Grumbach 提交者: Johannes Berg

iwlwifi: pcie: fix race in queue unmapping

When a queue is disabled, it frees all its entries. Later,
the op_mode might still get notifications from the firmware
that triggers to free entries in the tx queue. The transport
should be prepared for these races and know to ignore
reclaim calls on queues that have been disabled and whose
entries have been freed.

Cc: stable@vger.kernel.org
Signed-off-by: NEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 622ebe99
......@@ -576,9 +576,12 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
spin_lock_bh(&txq->lock);
while (q->write_ptr != q->read_ptr) {
IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
txq_id, q->read_ptr);
iwl_pcie_txq_free_tfd(trans, txq);
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
}
txq->active = false;
spin_unlock_bh(&txq->lock);
}
......@@ -927,6 +930,12 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
spin_lock_bh(&txq->lock);
if (!txq->active) {
IWL_DEBUG_TX_QUEUES(trans, "Q %d inactive - ignoring idx %d\n",
txq_id, ssn);
goto out;
}
if (txq->q.read_ptr == tfd_num)
goto out;
......@@ -1103,6 +1112,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
(fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
(1 << SCD_QUEUE_STTS_REG_POS_WSL) |
SCD_QUEUE_STTS_REG_MSK);
trans_pcie->txq[txq_id].active = true;
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
txq_id, fifo, ssn & 0xff);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册