From: "Luis R. Rodriguez" <lrodriguez@atheros.com>
To: linville@tuxdriver.com
Cc: linux-wireless@vger.kernel.org, Felix Fietkau <nbd@openwrt.org>
Subject: [PATCH 17/24] ath9k: fix queue stopping threshold
Date: Sat, 12 Jun 2010 00:33:55 -0400 [thread overview]
Message-ID: <1276317242-15540-18-git-send-email-lrodriguez@atheros.com> (raw)
In-Reply-To: <1276317242-15540-1-git-send-email-lrodriguez@atheros.com>
From: Felix Fietkau <nbd@openwrt.org>
ath9k tries to prevent WMM queue tx buffer starvation caused by
traffic on different queues by limiting the number of pending frames
in a tx queue (tracked in the ath_buf structure). This had a leak
issue, because the a skb can be reassigned to a different ath_buf
in the tx path, causing the pending frame counter to become inaccurate.
To fix this, track the number of frames in an array in the softc,
using the mac80211 queue mapping as index.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 3 +-
drivers/net/wireless/ath/ath9k/xmit.c | 53 +++++++++++++++++--------------
2 files changed, 30 insertions(+), 26 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 6aa8fa6..1a19aea 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -207,7 +207,6 @@ struct ath_txq {
struct list_head txq_fifo_pending;
u8 txq_headidx;
u8 txq_tailidx;
- int pending_frames;
};
struct ath_atx_ac {
@@ -245,7 +244,6 @@ struct ath_buf {
struct ath_buf_state bf_state;
dma_addr_t bf_dmacontext;
struct ath_wiphy *aphy;
- struct ath_txq *txq;
};
struct ath_atx_tid {
@@ -296,6 +294,7 @@ struct ath_tx {
struct list_head txbuf;
struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
struct ath_descdma txdma;
+ int pending_frames[WME_NUM_AC];
};
struct ath_rx_edma {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 9bff6c5..875b8b4 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1760,7 +1760,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_txq *txq = txctl->txq;
struct ath_buf *bf;
- int r;
+ int q, r;
bf = ath_tx_get_buffer(sc);
if (!bf) {
@@ -1768,14 +1768,6 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
return -1;
}
- bf->txq = txctl->txq;
- spin_lock_bh(&bf->txq->axq_lock);
- if (++bf->txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
- ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
- txq->stopped = 1;
- }
- spin_unlock_bh(&bf->txq->axq_lock);
-
r = ath_tx_setup_buffer(hw, bf, skb, txctl);
if (unlikely(r)) {
ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n");
@@ -1796,6 +1788,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
return r;
}
+ q = skb_get_queue_mapping(skb);
+ if (q >= 4)
+ q = 0;
+
+ spin_lock_bh(&txq->axq_lock);
+ if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) {
+ ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
+ txq->stopped = 1;
+ }
+ spin_unlock_bh(&txq->axq_lock);
+
ath_tx_start_dma(sc, bf, txctl);
return 0;
@@ -1865,7 +1868,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
- int padpos, padsize;
+ int q, padpos, padsize;
ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
@@ -1904,8 +1907,16 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL))
ath9k_tx_status(hw, skb);
- else
+ else {
+ q = skb_get_queue_mapping(skb);
+ if (q >= 4)
+ q = 0;
+
+ if (--sc->tx.pending_frames[q] < 0)
+ sc->tx.pending_frames[q] = 0;
+
ieee80211_tx_status(hw, skb);
+ }
}
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
@@ -1926,13 +1937,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
tx_flags |= ATH_TX_XRETRY;
}
- if (bf->txq) {
- spin_lock_bh(&bf->txq->axq_lock);
- bf->txq->pending_frames--;
- spin_unlock_bh(&bf->txq->axq_lock);
- bf->txq = NULL;
- }
-
dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
ath_tx_complete(sc, skb, bf->aphy, tx_flags);
ath_debug_stat_tx(sc, txq, bf, ts);
@@ -2020,13 +2024,14 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
{
int qnum;
+ qnum = ath_get_mac80211_qnum(txq->axq_class, sc);
+ if (qnum == -1)
+ return;
+
spin_lock_bh(&txq->axq_lock);
- if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
- qnum = ath_get_mac80211_qnum(txq->axq_class, sc);
- if (qnum != -1) {
- ath_mac80211_start_queue(sc, qnum);
- txq->stopped = 0;
- }
+ if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
+ ath_mac80211_start_queue(sc, qnum);
+ txq->stopped = 0;
}
spin_unlock_bh(&txq->axq_lock);
}
--
1.6.3.3
next prev parent reply other threads:[~2010-06-12 4:34 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-12 4:33 [PATCH 00/24] ath9k: new ANI, PAPrD and few fixes and cleanups Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 01/24] ath9k_hw: move clock definitions from hw.c to hw.h Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 02/24] ath9k_hw: fix clock rate calculations for ANI Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 03/24] ath9k_hw: clear MIB interrupt causes when skipping ANI adjustments Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 04/24] ath9k_hw: allow for spliting up ANI operations by family Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 05/24] ath9k_hw: add register definitions for the new ANI Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 06/24] ath9k_hw: inform ANI calibration when scanning Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 07/24] ath9k: add new ANI implementation for AR9003 Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 08/24] ath9k_hw: enable ANI " Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 09/24] ath9k_hw: reduce delay on programming INI on AR9003 Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 10/24] ath9k_hw: update 5 GHz tx gain tables for femless and high power PA Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 11/24] ath9k: fix mac80211 queue lookup for waking up queues Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 12/24] ath9k_htc: use common WMM AC definitions instead of ath9k ones Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 13/24] ath9k: remove duplicate WMM AC definitions Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 14/24] ath9k: remove declarations of some nonexistant functions Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 15/24] ath9k: make ath_get_hal_qnum static Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 16/24] ath9k: fix extending the rx timestamp with the hardware TSF Luis R. Rodriguez
2010-06-12 4:33 ` Luis R. Rodriguez [this message]
2010-06-12 4:33 ` [PATCH 18/24] ath9k: add a debugfs entry for ignoring CCA on the extension channel in HT40 Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 19/24] ath9k_hw: remove a useless function for setting the mac address Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 20/24] ath9k_hw: add register definitions related to PA predistortion Luis R. Rodriguez
2010-06-12 4:33 ` [PATCH 21/24] ath9k_hw: add support for parsing PA predistortion related EEPROM fields Luis R. Rodriguez
2010-06-12 4:34 ` [PATCH 22/24] ath9k_hw: add functions for controlling PA predistortion calibration Luis R. Rodriguez
2010-06-12 4:34 ` [PATCH 23/24] ath9k: implement PA predistortion support Luis R. Rodriguez
2010-06-12 4:34 ` [PATCH 24/24] ath9k: enable AR9003 PCI IDs Luis R. Rodriguez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1276317242-15540-18-git-send-email-lrodriguez@atheros.com \
--to=lrodriguez@atheros.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=nbd@openwrt.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox