ath9k: Measure per-station airtime usage
Toke Høiland-Jørgensen
maintainerRFC 1/1 ath9k: Measure per-station airtime usage
This is my attempt to add per-station airtime usage accounting to ath9k. For now I just export it to a new debugfs entry, but my plan is to use it to make (station) scheduling decisions. However, before attempting that I would like some feedback from someone more familiar with the ath9k than me as to whether this way of measuring airtime usage is likely to give reasonable results.
I realise that there's probably some things I'm missing, but an initial test run indicates that the values are at least in the right ballpark (I get a total of ~170k usecs of measured airtime per 200 ms sampling interval when running three simultaneous TCP streams to three different stations).
So can anyone comment on whether I'm on the right track here? And possibly provide some more detail as to what I'm missing and how to remedy that?
Many thanks in advance,
-Toke
---
drivers/net/wireless/ath/ath9k/ath9k.h +3 -0
@@ -264,6 +264,7 @@ struct ath_node {#ifdef CONFIG_ATH9K_STATION_STATISTICS struct ath_rx_rate_stats rx_rate_stats; +struct ath_airtime_stats airtime_stats;#endif u8 key_idx[4 ];
@@ -564,6 +565,8 @@ void ath_txq_schedule_all(struct ath_softc *sc);int ath_tx_init (struct ath_softc *sc,int nbufs);int ath_txq_update (struct ath_softc *sc,int qnum,struct ath9k_tx_queue_info *q); +u32 ath_pkt_duration (struct ath_softc *sc,u8 rix,int pktlen, +int width,int half_gi,bool shortPreamble);void ath_update_max_aggr_framelen (struct ath_softc *sc,int queue,int txop);void ath_assign_seq (struct ath_common *common,struct sk_buff *skb); int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
drivers/net/wireless/ath/ath9k/debug.h +21 -0
@@ -223,6 +223,11 @@ struct ath_rx_rate_stats { } cck_stats[4 ]; }; +struct ath_airtime_stats { +u32 rx_airtime; +u32 tx_airtime; +}; +#define ANT_MAIN 0#define ANT_ALT 1
@@ -316,12 +321,28 @@ ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause)void ath_debug_rate_stats (struct ath_softc *sc,struct ath_rx_status *rs,struct sk_buff *skb); +void ath_debug_tx_airtime (struct ath_softc *sc, +struct ath_node *an, +struct ath_tx_status *ts); +void ath_debug_rx_airtime (struct ath_softc *sc, +struct ath_rx_status *rs, +struct sk_buff *skb);#else static inline void ath_debug_rate_stats (struct ath_softc *sc,struct ath_rx_status *rs,struct sk_buff *skb) { } +static inline void ath_debug_tx_airtime (struct ath_softc *sc, +struct ath_node *an, +struct ath_tx_status *ts) +{ +} +static inline void ath_debug_rx_airtime (struct ath_softc *sc, +struct ath_rx_status *rs, +struct sk_buff *skb) +{ +}#endif /* CONFIG_ATH9K_STATION_STATISTICS */ #endif /* DEBUG_H */
drivers/net/wireless/ath/ath9k/debug_sta.c +102 -0
112 lines not on this page · raw message
drivers/net/wireless/ath/ath9k/recv.c +1 -0
@@ -1137,6 +1137,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)ath9k_antenna_check (sc, &rs);ath9k_apply_ampdu_details (sc, &rs, rxs);ath_debug_rate_stats (sc, &rs, skb); +ath_debug_rx_airtime (sc, &rs, skb); hdr = (struct ieee80211_hdr *)skb->data;if (ieee80211_is_ack (hdr->frame_control))
drivers/net/wireless/ath/ath9k/xmit.c +3 -2
@@ -481,6 +481,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, } an = (struct ath_node *)sta->drv_priv; +ath_debug_tx_airtime (sc, an, ts); tid =ath_get_skb_tid (sc, an, skb); seq_first = tid->seq_start; isba = ts->ts_flags &ATH9K_TX_BA ;
@@ -1024,8 +1025,8 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,* width - 0 for 20 MHz, 1 for 40 MHz * half_gi - to use 4us v/s 3.6 us for symbol time */ -static u32 ath_pkt_duration (struct ath_softc *sc,u8 rix,int pktlen, -int width,int half_gi,bool shortPreamble) +u32 ath_pkt_duration (struct ath_softc *sc,u8 rix,int pktlen, +int width,int half_gi,bool shortPreamble) {u32 nbits, nsymbits, duration, nsymbols;int streams;
Quoted 16 lines · Toke H?iland-J?rgensen
This is my attempt to add per-station airtime usage accounting to ath9k. For now I just export it to a new debugfs entry, but my plan is to use it to make (station) scheduling decisions. However, before attempting that I would like some feedback from someone more familiar with the ath9k than me as to whether this way of measuring airtime usage is likely to give reasonable results.
I realise that there's probably some things I'm missing, but an initial test run indicates that the values are at least in the right ballpark (I get a total of ~170k usecs of measured airtime per 200 ms sampling interval when running three simultaneous TCP streams to three different stations).
So can anyone comment on whether I'm on the right track here? And possibly provide some more detail as to what I'm missing and how to remedy that?
[...]
drivers/net/wireless/ath/ath9k/debug_sta.c static const struct file_operations fops_node_recv = { · line 254
Quoted 11 lines
drivers/net/wireless/ath/ath9k/debug_sta.c +10
-0+void ath_debug_tx_airtime (struct ath_softc *sc, +struct ath_node *an, +struct ath_tx_status *ts) +{ +struct ath_airtime_stats *astats; + +rcu_read_lock (); + + astats = &an->airtime_stats; + astats->tx_airtime += ts->duration;
I'm not ath9k expert but this seems to be oblivious to tx retries. The ts->duration is acquired from the last used tx rate for given frame. Or am I missing something?
I think you should use ts->ts_rateindex and ts->ts_longretry to factor in retries (see ath_tx_rc_status).
Micha?
Toke Høiland-Jørgensen
maintainerQuoted 6 lines · Michal Kazior
Quoted 6 lines
drivers/net/wireless/ath/ath9k/debug_sta.c +6
-0+void ath_debug_tx_airtime (struct ath_softc *sc, +struct ath_node *an, +struct ath_tx_status *ts) +{ +struct ath_airtime_stats *astats; +
Quoted 8 lines
drivers/net/wireless/ath/ath9k/debug_sta.c static const struct file_operations fops_node_recv = { · line 254
Quoted 4 lines
drivers/net/wireless/ath/ath9k/debug_sta.c +4
-0+rcu_read_lock (); + + astats = &an->airtime_stats; + astats->tx_airtime += ts->duration;I'm not ath9k expert but this seems to be oblivious to tx retries. The
ts->durationis acquired from the last used tx rate for given frame. Or am I missing something?
No, don't think you are. Wasn't sure what exactly that duration field included, but I think you're right that it doesn't factor in retries.
Quoted 2 lines
I think you should use
ts->ts_rateindexandts->ts_longretryto factor in retries (seeath_tx_rc_status).
I'll go digging. Thanks, this was exactly the kind of feedback I had hoped for! :)
-Toke