This adds a patch that introduces airtime fairness scheduling to ath9k, which can significantly improve network efficiency in mixed-rate environments. Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk> Signed-off-by: Felix Fietkau <nbd@nbd.name>master
parent
b3a871dd3d
commit
47bc081e76
@ -0,0 +1,35 @@ |
|||||||
|
From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@toke.dk>
|
||||||
|
Date: Mon, 5 Dec 2016 13:27:37 +0200
|
||||||
|
Subject: [PATCH] ath9k: Introduce airtime fairness scheduling between stations
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This reworks the ath9k driver to schedule transmissions to connected
|
||||||
|
stations in a way that enforces airtime fairness between them. It
|
||||||
|
accomplishes this by measuring the time spent transmitting to or
|
||||||
|
receiving from a station at TX and RX completion, and accounting this to
|
||||||
|
a per-station, per-QoS level airtime deficit. Then, an FQ-CoDel based
|
||||||
|
deficit scheduler is employed at packet dequeue time, to control which
|
||||||
|
station gets the next transmission opportunity.
|
||||||
|
|
||||||
|
Airtime fairness can significantly improve the efficiency of the network
|
||||||
|
when station rates vary. The following throughput values are from a
|
||||||
|
simple three-station test scenario, where two stations operate at the
|
||||||
|
highest HT20 rate, and one station at the lowest, and the scheduler is
|
||||||
|
employed at the access point:
|
||||||
|
|
||||||
|
Before / After
|
||||||
|
Fast station 1: 19.17 / 25.09 Mbps
|
||||||
|
Fast station 2: 19.83 / 25.21 Mbps
|
||||||
|
Slow station: 2.58 / 1.77 Mbps
|
||||||
|
Total: 41.58 / 52.07 Mbps
|
||||||
|
|
||||||
|
The benefit of airtime fairness goes up the more stations are present.
|
||||||
|
In a 30-station test with one station artificially limited to 1 Mbps,
|
||||||
|
we have seen aggregate throughput go from 2.14 to 17.76 Mbps.
|
||||||
|
|
||||||
|
Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
|
||||||
|
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||||
|
---
|
||||||
|
|
@ -0,0 +1,62 @@ |
|||||||
|
From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@toke.dk>
|
||||||
|
Date: Mon, 5 Dec 2016 13:27:38 +0200
|
||||||
|
Subject: [PATCH] ath9k: Turn ath_txq_lock/unlock() into static inlines.
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
These are one-line functions that just call spin_lock/unlock_bh(); turn
|
||||||
|
them into static inlines to avoid the function call overhead.
|
||||||
|
|
||||||
|
Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
|
||||||
|
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||||
|
@@ -558,6 +558,15 @@ static inline void ath_chanctx_check_act
|
||||||
|
|
||||||
|
#endif /* CPTCFG_ATH9K_CHANNEL_CONTEXT */
|
||||||
|
|
||||||
|
+static inline void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
|
+{
|
||||||
|
+ spin_lock_bh(&txq->axq_lock);
|
||||||
|
+}
|
||||||
|
+static inline void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
|
+{
|
||||||
|
+ spin_unlock_bh(&txq->axq_lock);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void ath_startrecv(struct ath_softc *sc);
|
||||||
|
bool ath_stoprecv(struct ath_softc *sc);
|
||||||
|
u32 ath_calcrxfilter(struct ath_softc *sc);
|
||||||
|
@@ -565,8 +574,6 @@ int ath_rx_init(struct ath_softc *sc, in
|
||||||
|
void ath_rx_cleanup(struct ath_softc *sc);
|
||||||
|
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
|
||||||
|
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
|
||||||
|
-void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq);
|
||||||
|
-void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq);
|
||||||
|
void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq);
|
||||||
|
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
|
||||||
|
bool ath_drain_all_txq(struct ath_softc *sc);
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/xmit.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
|
||||||
|
@@ -98,18 +98,6 @@ static void ath_tx_status(struct ieee802
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
|
- __acquires(&txq->axq_lock)
|
||||||
|
-{
|
||||||
|
- spin_lock_bh(&txq->axq_lock);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
|
- __releases(&txq->axq_lock)
|
||||||
|
-{
|
||||||
|
- spin_unlock_bh(&txq->axq_lock);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
|
__releases(&txq->axq_lock)
|
||||||
|
{
|
Loading…
Reference in new issue