Date:2011-05-19 11:33:45 (12 years 10 months ago)
Author:nbd
Commit:f538e8b59b6f97c96be4f8ba49a4a030851f088e
Message:ath9k: fix some locking issues in the tx fifo cleanup patch

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@26947 3c298f89-4303-0410-b956-a3cf2f4a3e73
Files: package/mac80211/patches/580-ath9k_tx_fifo_cleanup.patch (5 diffs)

Change Details

package/mac80211/patches/580-ath9k_tx_fifo_cleanup.patch
467467 }
468468
469469 static void ath_tx_complete_poll_work(struct work_struct *work)
470@@ -2237,17 +2193,17 @@ void ath_tx_tasklet(struct ath_softc *sc
470@@ -2237,17 +2193,16 @@ void ath_tx_tasklet(struct ath_softc *sc
471471
472472 void ath_tx_edma_tasklet(struct ath_softc *sc)
473473 {
...... 
481481     int status;
482482- int txok;
483483
484+ spin_lock_bh(&txq->axq_lock);
485484     for (;;) {
486485- status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
487486+ status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts);
488487         if (status == -EINPROGRESS)
489488             break;
490489         if (status == -EIO) {
491@@ -2257,16 +2213,16 @@ void ath_tx_edma_tasklet(struct ath_soft
490@@ -2257,12 +2212,13 @@ void ath_tx_edma_tasklet(struct ath_soft
492491         }
493492
494493         /* Skip beacon completions */
...... 
497496             continue;
498497
499498- txq = &sc->tx.txq[txs.qid];
500+ ath_dbg(common, ATH_DBG_XMIT,
501+ "Tx status, descid=%04x\n", ts.desc_id);
502
503- spin_lock_bh(&txq->axq_lock);
504- if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
505- spin_unlock_bh(&txq->axq_lock);
506- return;
507- }
508499+ txq = &sc->tx.txq[ts.qid];
509+
510+ if (list_empty(&txq->txq_fifo[txq->txq_tailidx]))
511+ break;
512500
513         bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
514                       struct ath_buf, list);
515@@ -2275,43 +2231,24 @@ void ath_tx_edma_tasklet(struct ath_soft
501         spin_lock_bh(&txq->axq_lock);
502+
503         if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
504             spin_unlock_bh(&txq->axq_lock);
505             return;
506@@ -2275,41 +2231,21 @@ void ath_tx_edma_tasklet(struct ath_soft
516507         INIT_LIST_HEAD(&bf_head);
517508         list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
518509                   &lastbf->list);
...... 
524515- spin_unlock_bh(&txq->axq_lock);
525516
526517- txok = !(txs.ts_status & ATH9K_TXERR_MASK);
527+ if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
528+ INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
529
518-
530519- if (!bf_isampdu(bf)) {
531520- if (txs.ts_status & ATH9K_TXERR_XRETRY)
532521- bf->bf_state.bf_type |= BUF_XRETRY;
533522- ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true);
534523- }
535+ if (!list_empty(&txq->axq_q)) {
536+ struct list_head bf_q;
537
524-
538525- if (bf_isampdu(bf))
539526- ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs,
540527- txok, true);
541528- else
542529- ath_tx_complete_buf(sc, bf, txq, &bf_head,
543530- &txs, txok, 0);
544-
531+ if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
532+ INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
533
545534- spin_lock_bh(&txq->axq_lock);
546+ INIT_LIST_HEAD(&bf_q);
547+ txq->axq_link = NULL;
548+ list_splice_tail_init(&txq->axq_q, &bf_q);
549+ ath_tx_txqaddbuf(sc, txq, &bf_q, true);
550+ }
551+ }
535+ if (!list_empty(&txq->axq_q)) {
536+ struct list_head bf_q;
552537
553538- if (!list_empty(&txq->txq_fifo_pending)) {
554539- INIT_LIST_HEAD(&bf_head);
...... 
560545- ath_tx_txqaddbuf(sc, txq, &bf_head);
561546- } else if (sc->sc_flags & SC_OP_TXAGGR)
562547- ath_txq_schedule(sc, txq);
563+ ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
548+ INIT_LIST_HEAD(&bf_q);
549+ txq->axq_link = NULL;
550+ list_splice_tail_init(&txq->axq_q, &bf_q);
551+ ath_tx_txqaddbuf(sc, txq, &bf_q, true);
552+ }
553+ }
564554
565- spin_unlock_bh(&txq->axq_lock);
555+ ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
556         spin_unlock_bh(&txq->axq_lock);
566557     }
567+ spin_unlock_bh(&txq->axq_lock);
568558 }
569
570 /*****************/
571559--- a/drivers/net/wireless/ath/ath9k/ath9k.h
572560+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
573561@@ -179,7 +179,7 @@ enum ATH_AGGR_STATUS {

Archive Download the corresponding diff file



interactive