Changeset 36267


Ignore:
Timestamp:
2013-04-08T00:05:45+02:00 (5 years ago)
Author:
nbd
Message:

ath9k: fix a tx processing race condition on AR9300+

Signed-off-by: Felix Fietkau <nbd@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/package/mac80211/patches/300-pending_work.patch

    r36266 r36267  
    10371037                        MAJOR_VERSION_REQ, MINOR_VERSION_REQ); 
    10381038                return -EINVAL; 
     1039--- a/drivers/net/wireless/ath/ath9k/xmit.c 
     1040+++ b/drivers/net/wireless/ath/ath9k/xmit.c 
     1041@@ -516,8 +516,7 @@ static void ath_tx_complete_aggr(struct  
     1042                 * not a holding desc. 
     1043                 */ 
     1044                INIT_LIST_HEAD(&bf_head); 
     1045-               if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || 
     1046-                   bf_next != NULL || !bf_last->bf_stale) 
     1047+               if (bf_next != NULL || !bf_last->bf_stale) 
     1048                        list_move_tail(&bf->list, &bf_head); 
     1049  
     1050                if (!txpending || (tid->state & AGGR_CLEANUP)) { 
     1051@@ -537,8 +536,7 @@ static void ath_tx_complete_aggr(struct  
     1052                                !txfail); 
     1053                } else { 
     1054                        /* retry the un-acked ones */ 
     1055-                       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && 
     1056-                           bf->bf_next == NULL && bf_last->bf_stale) { 
     1057+                       if (bf->bf_next == NULL && bf_last->bf_stale) { 
     1058                                struct ath_buf *tbf; 
     1059  
     1060                                tbf = ath_clone_txbuf(sc, bf_last); 
     1061@@ -2264,6 +2262,7 @@ void ath_tx_edma_tasklet(struct ath_soft 
     1062        struct ath_txq *txq; 
     1063        struct ath_buf *bf, *lastbf; 
     1064        struct list_head bf_head; 
     1065+       struct list_head *fifo_list; 
     1066        int status; 
     1067  
     1068        for (;;) { 
     1069@@ -2291,20 +2290,24 @@ void ath_tx_edma_tasklet(struct ath_soft 
     1070  
     1071                TX_STAT_INC(txq->axq_qnum, txprocdesc); 
     1072  
     1073-               if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { 
     1074+               fifo_list = &txq->txq_fifo[txq->txq_tailidx]; 
     1075+               if (list_empty(fifo_list)) { 
     1076                        ath_txq_unlock(sc, txq); 
     1077                        return; 
     1078                } 
     1079  
     1080-               bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx], 
     1081-                                     struct ath_buf, list); 
     1082+               bf = list_first_entry(fifo_list, struct ath_buf, list); 
     1083+               if (bf->bf_stale) { 
     1084+                       list_del(&bf->list); 
     1085+                       ath_tx_return_buffer(sc, bf); 
     1086+                       bf = list_first_entry(fifo_list, struct ath_buf, list); 
     1087+               } 
     1088+ 
     1089                lastbf = bf->bf_lastbf; 
     1090  
     1091                INIT_LIST_HEAD(&bf_head); 
     1092-               list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx], 
     1093-                                 &lastbf->list); 
     1094- 
     1095-               if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { 
     1096+               if (list_is_last(&lastbf->list, fifo_list)) { 
     1097+                       list_splice_tail_init(fifo_list, &bf_head); 
     1098                        INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); 
     1099  
     1100                        if (!list_empty(&txq->axq_q)) { 
     1101@@ -2315,6 +2318,11 @@ void ath_tx_edma_tasklet(struct ath_soft 
     1102                                list_splice_tail_init(&txq->axq_q, &bf_q); 
     1103                                ath_tx_txqaddbuf(sc, txq, &bf_q, true); 
     1104                        } 
     1105+               } else { 
     1106+                       lastbf->bf_stale = true; 
     1107+                       if (bf != lastbf) 
     1108+                               list_cut_position(&bf_head, fifo_list, 
     1109+                                                 lastbf->list.prev); 
     1110                } 
     1111  
     1112                ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); 
Note: See TracChangeset for help on using the changeset viewer.