diff mbox

iwlwifi: pcie: don't panic on host commands in iwldvm

Message ID 1390214977-29202-1-git-send-email-egrumbach@gmail.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Emmanuel Grumbach Jan. 20, 2014, 10:49 a.m. UTC
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

None of the devices supported by iwldvm have support for
shadow registers. This means that we wake the NIC
when we increment the write pointer on Tx ring.
This happened even before my bad commit mentionned below.
Since my commit below, we wake up the NIC when we put a
host command on the ring regardless of shadow register
support. This means that in iwldvm (when the NIC doesn't
support shadow register), we wake up the NIC twice:

pcie_enqueue_hcmd:
	wake up the NIC
	iwl_pcie_txq_inc_wr_ptr:
		wake up the NIC - no shadow reg support

Since waking up the NIC means that we need to acquire a
spinlock, this obviously leads to a recursive spinlock
and hence a freeze.

Fixes: b9439491055a ("iwlwifi: pcie: keep the NIC awake when commands are in flight")
Reported-by: Janusz Dziedzic <janusz.dziedzic@gmail.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 drivers/net/wireless/iwlwifi/pcie/tx.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Kalle Valo Jan. 23, 2014, 3:46 p.m. UTC | #1
Emmanuel Grumbach <egrumbach@gmail.com> writes:

> From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
>
> None of the devices supported by iwldvm have support for
> shadow registers. This means that we wake the NIC
> when we increment the write pointer on Tx ring.
> This happened even before my bad commit mentionned below.
> Since my commit below, we wake up the NIC when we put a
> host command on the ring regardless of shadow register
> support. This means that in iwldvm (when the NIC doesn't
> support shadow register), we wake up the NIC twice:
>
> pcie_enqueue_hcmd:
> 	wake up the NIC
> 	iwl_pcie_txq_inc_wr_ptr:
> 		wake up the NIC - no shadow reg support
>
> Since waking up the NIC means that we need to acquire a
> spinlock, this obviously leads to a recursive spinlock
> and hence a freeze.
>
> Fixes: b9439491055a ("iwlwifi: pcie: keep the NIC awake when commands are in flight")
> Reported-by: Janusz Dziedzic <janusz.dziedzic@gmail.com>
> Reviewed-by: Johannes Berg <johannes.berg@intel.com>
> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

Ah, this is why my laptop was hanging during boot with latest
wireless-testing? Thanks for fixing this. 

FWIW:

Tested-by: Kalle Valo <kvalo@adurom.com>
diff mbox

Patch

diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 3b14fa8..3d54900 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -289,13 +289,15 @@  static void iwl_pcie_txq_inval_byte_cnt_tbl(struct iwl_trans *trans,
  */
 void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq)
 {
+	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 	u32 reg = 0;
 	int txq_id = txq->q.id;
 
 	if (txq->need_update == 0)
 		return;
 
-	if (trans->cfg->base_params->shadow_reg_enable) {
+	if (trans->cfg->base_params->shadow_reg_enable ||
+	    txq_id == trans_pcie->cmd_queue) {
 		/* shadow register enabled */
 		iwl_write32(trans, HBUS_TARG_WRPTR,
 			    txq->q.write_ptr | (txq_id << 8));