Просмотр исходного кода

ath9k: fix some locking issues in the tx fifo cleanup patch

SVN-Revision: 26947
Felix Fietkau 15 лет назад
Родитель
Сommit
512be5ce46
1 измененных файлов с 23 добавлено и 35 удалено
  1. 23 35
      package/mac80211/patches/580-ath9k_tx_fifo_cleanup.patch

+ 23 - 35
package/mac80211/patches/580-ath9k_tx_fifo_cleanup.patch

@@ -467,7 +467,7 @@
  }
  }
  
  
  static void ath_tx_complete_poll_work(struct work_struct *work)
  static void ath_tx_complete_poll_work(struct work_struct *work)
-@@ -2237,17 +2193,17 @@ void ath_tx_tasklet(struct ath_softc *sc
+@@ -2237,17 +2193,16 @@ void ath_tx_tasklet(struct ath_softc *sc
  
  
  void ath_tx_edma_tasklet(struct ath_softc *sc)
  void ath_tx_edma_tasklet(struct ath_softc *sc)
  {
  {
@@ -481,14 +481,13 @@
  	int status;
  	int status;
 -	int txok;
 -	int txok;
  
  
-+	spin_lock_bh(&txq->axq_lock);
  	for (;;) {
  	for (;;) {
 -		status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
 -		status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
 +		status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts);
 +		status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts);
  		if (status == -EINPROGRESS)
  		if (status == -EINPROGRESS)
  			break;
  			break;
  		if (status == -EIO) {
  		if (status == -EIO) {
-@@ -2257,16 +2213,16 @@ void ath_tx_edma_tasklet(struct ath_soft
+@@ -2257,12 +2212,13 @@ void ath_tx_edma_tasklet(struct ath_soft
  		}
  		}
  
  
  		/* Skip beacon completions */
  		/* Skip beacon completions */
@@ -497,22 +496,14 @@
  			continue;
  			continue;
  
  
 -		txq = &sc->tx.txq[txs.qid];
 -		txq = &sc->tx.txq[txs.qid];
-+		ath_dbg(common, ATH_DBG_XMIT,
-+			"Tx status, descid=%04x\n", ts.desc_id);
- 
--		spin_lock_bh(&txq->axq_lock);
--		if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
--			spin_unlock_bh(&txq->axq_lock);
--			return;
--		}
 +		txq = &sc->tx.txq[ts.qid];
 +		txq = &sc->tx.txq[ts.qid];
-+
-+		if (list_empty(&txq->txq_fifo[txq->txq_tailidx]))
-+			break;
  
  
- 		bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
- 				      struct ath_buf, list);
-@@ -2275,43 +2231,24 @@ void ath_tx_edma_tasklet(struct ath_soft
+ 		spin_lock_bh(&txq->axq_lock);
++
+ 		if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
+ 			spin_unlock_bh(&txq->axq_lock);
+ 			return;
+@@ -2275,41 +2231,21 @@ void ath_tx_edma_tasklet(struct ath_soft
  		INIT_LIST_HEAD(&bf_head);
  		INIT_LIST_HEAD(&bf_head);
  		list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
  		list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
  				  &lastbf->list);
  				  &lastbf->list);
@@ -524,31 +515,25 @@
 -		spin_unlock_bh(&txq->axq_lock);
 -		spin_unlock_bh(&txq->axq_lock);
  
  
 -		txok = !(txs.ts_status & ATH9K_TXERR_MASK);
 -		txok = !(txs.ts_status & ATH9K_TXERR_MASK);
-+		if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
-+			INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
- 
+-
 -		if (!bf_isampdu(bf)) {
 -		if (!bf_isampdu(bf)) {
 -			if (txs.ts_status & ATH9K_TXERR_XRETRY)
 -			if (txs.ts_status & ATH9K_TXERR_XRETRY)
 -				bf->bf_state.bf_type |= BUF_XRETRY;
 -				bf->bf_state.bf_type |= BUF_XRETRY;
 -			ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true);
 -			ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true);
 -		}
 -		}
-+			if (!list_empty(&txq->axq_q)) {
-+				struct list_head bf_q;
- 
+-
 -		if (bf_isampdu(bf))
 -		if (bf_isampdu(bf))
 -			ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs,
 -			ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs,
 -					     txok, true);
 -					     txok, true);
 -		else
 -		else
 -			ath_tx_complete_buf(sc, bf, txq, &bf_head,
 -			ath_tx_complete_buf(sc, bf, txq, &bf_head,
 -					    &txs, txok, 0);
 -					    &txs, txok, 0);
--
++		if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
++			INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
+ 
 -		spin_lock_bh(&txq->axq_lock);
 -		spin_lock_bh(&txq->axq_lock);
-+				INIT_LIST_HEAD(&bf_q);
-+				txq->axq_link = NULL;
-+				list_splice_tail_init(&txq->axq_q, &bf_q);
-+				ath_tx_txqaddbuf(sc, txq, &bf_q, true);
-+			}
-+		}
++			if (!list_empty(&txq->axq_q)) {
++				struct list_head bf_q;
  
  
 -		if (!list_empty(&txq->txq_fifo_pending)) {
 -		if (!list_empty(&txq->txq_fifo_pending)) {
 -			INIT_LIST_HEAD(&bf_head);
 -			INIT_LIST_HEAD(&bf_head);
@@ -560,14 +545,17 @@
 -			ath_tx_txqaddbuf(sc, txq, &bf_head);
 -			ath_tx_txqaddbuf(sc, txq, &bf_head);
 -		} else if (sc->sc_flags & SC_OP_TXAGGR)
 -		} else if (sc->sc_flags & SC_OP_TXAGGR)
 -			ath_txq_schedule(sc, txq);
 -			ath_txq_schedule(sc, txq);
-+		ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
++				INIT_LIST_HEAD(&bf_q);
++				txq->axq_link = NULL;
++				list_splice_tail_init(&txq->axq_q, &bf_q);
++				ath_tx_txqaddbuf(sc, txq, &bf_q, true);
++			}
++		}
  
  
--		spin_unlock_bh(&txq->axq_lock);
++		ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
+ 		spin_unlock_bh(&txq->axq_lock);
  	}
  	}
-+	spin_unlock_bh(&txq->axq_lock);
  }
  }
- 
- /*****************/
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
 @@ -179,7 +179,7 @@ enum ATH_AGGR_STATUS {
 @@ -179,7 +179,7 @@ enum ATH_AGGR_STATUS {