Skip to content

Commit 7a89233

Browse files
tohojojmberg-intel
authored andcommitted
mac80211: Use Airtime-based Queue Limits (AQL) on packet dequeue
The previous commit added the ability to throttle stations when they queue too much airtime in the hardware. This commit enables the functionality by calculating the expected airtime usage of each packet that is dequeued from the TXQs in mac80211, and accounting that as pending airtime. The estimated airtime for each skb is stored in the tx_info, so we can subtract the same amount from the running total when the skb is freed or recycled. The throttling mechanism relies on this accounting to be accurate (i.e., that we are not freeing skbs without subtracting any airtime they were accounted for), so we put the subtraction into ieee80211_report_used_skb(). As an optimisation, we also subtract the airtime on regular TX completion, zeroing out the value stored in the packet afterwards, to avoid having to do an expensive lookup of the station from the packet data on every packet. This patch does *not* include any mechanism to wake a throttled TXQ again, on the assumption that this will happen anyway as a side effect of whatever freed the skb (most commonly a TX completion). Signed-off-by: Toke Høiland-Jørgensen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Johannes Berg <[email protected]>
1 parent 3ace10f commit 7a89233

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

include/net/mac80211.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,22 @@ struct ieee80211_tx_info {
10601060
};
10611061
};
10621062

1063+
static inline u16
1064+
ieee80211_info_set_tx_time_est(struct ieee80211_tx_info *info, u16 tx_time_est)
1065+
{
1066+
/* We only have 10 bits in tx_time_est, so store airtime
1067+
* in increments of 4us and clamp the maximum to 2**12-1
1068+
*/
1069+
info->tx_time_est = min_t(u16, tx_time_est, 4095) >> 2;
1070+
return info->tx_time_est << 2;
1071+
}
1072+
1073+
static inline u16
1074+
ieee80211_info_get_tx_time_est(struct ieee80211_tx_info *info)
1075+
{
1076+
return info->tx_time_est << 2;
1077+
}
1078+
10631079
/**
10641080
* struct ieee80211_tx_status - extended tx status info for rate control
10651081
*

net/mac80211/status.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,12 +670,26 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
670670
struct sk_buff *skb, bool dropped)
671671
{
672672
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
673+
u16 tx_time_est = ieee80211_info_get_tx_time_est(info);
673674
struct ieee80211_hdr *hdr = (void *)skb->data;
674675
bool acked = info->flags & IEEE80211_TX_STAT_ACK;
675676

676677
if (dropped)
677678
acked = false;
678679

680+
if (tx_time_est) {
681+
struct sta_info *sta;
682+
683+
rcu_read_lock();
684+
685+
sta = sta_info_get_by_addrs(local, hdr->addr1, hdr->addr2);
686+
ieee80211_sta_update_pending_airtime(local, sta,
687+
skb_get_queue_mapping(skb),
688+
tx_time_est,
689+
true);
690+
rcu_read_unlock();
691+
}
692+
679693
if (info->flags & IEEE80211_TX_INTFL_MLME_CONN_TX) {
680694
struct ieee80211_sub_if_data *sdata;
681695

@@ -877,6 +891,7 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
877891
struct ieee80211_bar *bar;
878892
int shift = 0;
879893
int tid = IEEE80211_NUM_TIDS;
894+
u16 tx_time_est;
880895

881896
rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
882897

@@ -986,6 +1001,17 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
9861001
ieee80211_sta_register_airtime(&sta->sta, tid,
9871002
info->status.tx_time, 0);
9881003

1004+
if ((tx_time_est = ieee80211_info_get_tx_time_est(info)) > 0) {
1005+
/* Do this here to avoid the expensive lookup of the sta
1006+
* in ieee80211_report_used_skb().
1007+
*/
1008+
ieee80211_sta_update_pending_airtime(local, sta,
1009+
skb_get_queue_mapping(skb),
1010+
tx_time_est,
1011+
true);
1012+
ieee80211_info_set_tx_time_est(info, 0);
1013+
}
1014+
9891015
if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
9901016
if (info->flags & IEEE80211_TX_STAT_ACK) {
9911017
if (sta->status_stats.lost_packets)

net/mac80211/tx.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3554,6 +3554,9 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
35543554

35553555
WARN_ON_ONCE(softirq_count() == 0);
35563556

3557+
if (!ieee80211_txq_airtime_check(hw, txq))
3558+
return NULL;
3559+
35573560
begin:
35583561
spin_lock_bh(&fq->lock);
35593562

@@ -3664,6 +3667,21 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
36643667
}
36653668

36663669
IEEE80211_SKB_CB(skb)->control.vif = vif;
3670+
3671+
if (local->airtime_flags & AIRTIME_USE_AQL) {
3672+
u32 airtime;
3673+
3674+
airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
3675+
skb->len);
3676+
if (airtime) {
3677+
airtime = ieee80211_info_set_tx_time_est(info, airtime);
3678+
ieee80211_sta_update_pending_airtime(local, tx.sta,
3679+
txq->ac,
3680+
airtime,
3681+
false);
3682+
}
3683+
}
3684+
36673685
return skb;
36683686

36693687
out:

0 commit comments

Comments
 (0)