All of lore.kernel.org
 help / color / mirror / Atom feed
* [ath9k-devel] [RFC] ath9k: fix tx queue selection
@ 2010-11-02 16:13 Björn Smedman
  2010-11-02 17:13   ` Felix Fietkau
  0 siblings, 1 reply; 31+ messages in thread
From: Björn Smedman @ 2010-11-02 16:13 UTC (permalink / raw)
  To: ath9k-devel

Hi all,

The following patch attempts to fix some problems with ath9k tx queue 
selection:

1. There was a posible mismatch between the queue selected for QoS packets 
(on which locking, queue start/stop and statistics where performed) and 
the queue actually used for TX. This is fixed by selecting the tx queue 
based on the TID of the 802.11 header for this type of packet.

2. Even with the above fix there was still a risk of mac80211 queue 
"deadlock" because the queue to stop was selected on the basis of the skb 
queue mapping whereas the queue to start was selected based on the hardware
tx queue to mac80211 queue mapping. These may not in all situations be one 
and the same.

This patch is against latest wireless-testing but I've only tested it 
against compat-wireless-2010-10-19 with openwrt patches on top (including 
Luis latest pcu lock patch) and some other patches I'm working on. If you 
can run wireless-testing directly, please give it a spin. For me it's a 
big improvement in stability under high tx/rx load. 

Any thoughts?

/Bj?rn

---
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a133878..bbc292a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1266,6 +1266,14 @@ static int ath9k_tx(struct ieee80211_hw *hw,
 		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
 	}
 
+	if (ieee80211_is_data_qos(hdr->frame_control)) {
+		u8 *qc = ieee80211_get_qos_ctl(hdr);
+		qnum = sc->tx.hwq_map[TID_TO_WME_AC(qc[0] & 0xf)];
+	} else
+		qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
+
+	txctl.txq = &sc->tx.txq[qnum];
+
 	/* Add the padding after the header if this is not already done */
 	padpos = ath9k_cmn_padpos(hdr->frame_control);
 	padsize = padpos & 3;
@@ -1276,9 +1284,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
 		memmove(skb->data, skb->data + padsize, padpos);
 	}
 
-	qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
-	txctl.txq = &sc->tx.txq[qnum];
-
 	ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
 
 	if (ath_tx_start(hw, skb, &txctl) != 0) {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f7da6b2..5be9d5e 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2011,17 +2011,17 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
 	tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
 }
 
-static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
+static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq,
+				    int qm)
 {
-	int qnum;
+	int q = qm;
 
-	qnum = ath_get_mac80211_qnum(txq->axq_class, sc);
-	if (qnum == -1)
-		return;
+        if (q >= 4)
+                q = 0;
 
 	spin_lock_bh(&txq->axq_lock);
-	if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
-		if (ath_mac80211_start_queue(sc, qnum))
+	if (txq->stopped && sc->tx.pending_frames[q] < ATH_MAX_QDEPTH) {
+		if (ath_mac80211_start_queue(sc, qm))
 			txq->stopped = 0;
 	}
 	spin_unlock_bh(&txq->axq_lock);
@@ -2037,6 +2037,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 	struct ath_tx_status ts;
 	int txok;
 	int status;
+	int qm;
 
 	ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
 		  txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
@@ -2124,12 +2125,14 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 			ath_tx_rc_status(bf, &ts, 0, txok, true);
 		}
 
+		qm = skb_get_queue_mapping(bf->bf_mpdu);
+
 		if (bf_isampdu(bf))
 			ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok);
 		else
 			ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
 
-		ath_wake_mac80211_queue(sc, txq);
+		ath_wake_mac80211_queue(sc, txq, qm);
 
 		spin_lock_bh(&txq->axq_lock);
 		if (sc->sc_flags & SC_OP_TXAGGR)
@@ -2199,6 +2202,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
 	struct list_head bf_head;
 	int status;
 	int txok;
+	int qm;
 
 	for (;;) {
 		status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
@@ -2253,13 +2257,15 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
 			ath_tx_rc_status(bf, &txs, 0, txok, true);
 		}
 
+		qm = skb_get_queue_mapping(bf->bf_mpdu);
+
 		if (bf_isampdu(bf))
 			ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
 		else
 			ath_tx_complete_buf(sc, bf, txq, &bf_head,
 					    &txs, txok, 0);
 
-		ath_wake_mac80211_queue(sc, txq);
+		ath_wake_mac80211_queue(sc, txq, qm);
 
 		spin_lock_bh(&txq->axq_lock);
 		if (!list_empty(&txq->txq_fifo_pending)) {

^ permalink raw reply related	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2010-11-03 17:48 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-02 16:13 [ath9k-devel] [RFC] ath9k: fix tx queue selection Björn Smedman
2010-11-02 17:13 ` Felix Fietkau
2010-11-02 17:13   ` Felix Fietkau
2010-11-02 17:37   ` Felix Fietkau
2010-11-02 17:37     ` Felix Fietkau
2010-11-02 18:20     ` Björn Smedman
2010-11-02 18:20       ` Björn Smedman
2010-11-02 18:54       ` Felix Fietkau
2010-11-02 18:54         ` Felix Fietkau
2010-11-02 19:16         ` Björn Smedman
2010-11-02 19:16           ` Björn Smedman
2010-11-02 22:11           ` Felix Fietkau
2010-11-02 22:11             ` Felix Fietkau
2010-11-03 11:35             ` Björn Smedman
2010-11-03 11:35               ` Björn Smedman
2010-11-03 11:53               ` Felix Fietkau
2010-11-03 11:53                 ` Felix Fietkau
2010-11-03 16:27                 ` Björn Smedman
2010-11-03 16:27                   ` Björn Smedman
2010-11-03 16:56                   ` Felix Fietkau
2010-11-03 16:56                     ` Felix Fietkau
2010-11-03 17:04                     ` Ben Greear
2010-11-03 17:04                       ` Ben Greear
2010-11-03 17:31                     ` Björn Smedman
2010-11-03 17:31                       ` Björn Smedman
2010-11-03 17:48                       ` Felix Fietkau
2010-11-03 17:48                         ` Felix Fietkau
2010-11-02 18:12   ` Björn Smedman
2010-11-02 18:12     ` Björn Smedman
2010-11-02 22:59   ` Helmut Schaa
2010-11-02 22:59     ` Helmut Schaa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.