[PATCH v1 4/4] wifi: ath11k: report tx airtime and enable airtime fairness
Julius Bairaktaris <[email protected]>
| Newsgroups | org.infradead.lists.ath11k,org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <[email protected]> |
mac80211's airtime scheduler charges sta->airtime[ac].deficit from one place, ieee80211_sta_register_airtime(). Unlike AQL there is no estimator fallback, and ath11k never calls it, so the ATF feature bit cannot be advertised on its own: the deficit would only ever be replenished, every station would stay permanently in credit, and the DRR would be inert. The bit is not a no-op in that state either, because it also moves txq insertion to the head of the active list, which __ieee80211_schedule_txq() documents as safe only because the DRR moves a station back once its deficit goes negative. fes_duration_us arrives with every PPDU's stats and is already accumulated into arsta->tx_duration a few lines above. Register it, and set the feature bit in the same change so the two cannot be separated. Measured on an IPQ8074 AP with two stations on one radio, a 1x1 VHT client at 433 Mbit/s and a 2x2 HE client, both receiving at once. Before, 'iw station set <mac> airtime_weight' is refused with -EOPNOTSUPP and the per-station airtime file reads zero. After, the weight is accepted and read back, TX airtime accumulates, and the per-AC deficits move. The fairness this delivers is coarse. Weighting the fast station 4:1 moves the slow station's share of airtime from 59.5% to 52.1% and the fast station's throughput from 315 to 392 Mbit/s: the direction is correct, the magnitude is not the ratio requested. The granularity is bounded by the driver's push model, since ieee80211_handle_wake_tx_queue() drains a selected txq whole into the hardware and the scheduler therefore reorders only between selections. Tightening the AQL limit to shorten those drains does not improve it: the share moves by one point and aggregate throughput falls from 401 to 178 Mbit/s. Finer control would require a TXQ scheduler in the driver. Two properties of the source are worth stating. fes_duration_us spans the frame exchange sequence, so it includes the SIFS and the responding BlockAck, time the radio spends receiving; the airtime registered is therefore larger than the airtime transmitted. And it is a per-PPDU field, so on a downlink MU PPDU each user is charged the whole sequence. No per-user duration is reported in these stats. On the firmware tested here every PPDU carried exactly one user, measured over 21051 PPDUs, so the MU case is latent rather than observed. Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.9.0.1-02146-QCAHKSWPL_SILICONZ-1 Assisted-by: Claude:claude-opus-5 Signed-off-by: Julius Bairaktaris <[email protected]> --- drivers/net/wireless/ath/ath11k/dp_rx.c | 9 +++++++++ drivers/net/wireless/ath/ath11k/mac.c | 2 ++ 2 files changed, 11 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 33425707c084..33c6fd9553a6 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -1485,6 +1485,15 @@ ath11k_update_per_peer_tx_stats(struct ath11k *ar, arsta->txrate.bw = ath11k_mac_bw_to_mac80211_bw(bw); arsta->tx_duration += tx_duration; + + /* tid is HTT_PPDU_STATS_NON_QOS_TID when no ack/BA TLV came with the + * PPDU; mask it so that airtime lands in a real access category rather + * than one chosen by the spare bits. + */ + if (tx_duration) + ieee80211_sta_register_airtime(sta, + tid & IEEE80211_QOS_CTL_TID_MASK, + tx_duration, 0); memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info)); /* PPDU stats reported for mgmt packet doesn't have valid tx bytes. diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 38f641bbc53c..40a2b6d2f804 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -10593,6 +10593,8 @@ static int __ath11k_mac_register(struct ath11k *ar) wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_AQL); + wiphy_ext_feature_set(ar->hw->wiphy, + NL80211_EXT_FEATURE_AIRTIME_FAIRNESS); wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR); if (test_bit(WMI_TLV_SERVICE_BSS_COLOR_OFFLOAD, ar->ab->wmi_ab.svc_map)) { -- 2.53.0