developer | 1de5e6c | 2022-06-27 11:23:25 +0800 | [diff] [blame] | 1 | From: Felix Fietkau <nbd@nbd.name> |
| 2 | Date: Mon, 20 Jun 2022 20:52:50 +0200 |
| 3 | Subject: [PATCH] mac80211: keep recently active tx queues in scheduling |
| 4 | list |
| 5 | |
| 6 | This allows proper deficit accounting to ensure that they don't carry their |
| 7 | deficit until the next time they become active |
| 8 | |
| 9 | Signed-off-by: Felix Fietkau <nbd@nbd.name> |
| 10 | --- |
| 11 | |
| 12 | --- a/net/mac80211/ieee80211_i.h |
| 13 | +++ b/net/mac80211/ieee80211_i.h |
| 14 | @@ -83,6 +83,13 @@ extern const u8 ieee80211_ac_to_qos_mask |
| 15 | |
| 16 | #define IEEE80211_MAX_NAN_INSTANCE_ID 255 |
| 17 | |
| 18 | + |
| 19 | +/* |
| 20 | + * Keep a station's queues on the active list for deficit accounting purposes |
| 21 | + * if it was active or queued during the last 100ms |
| 22 | + */ |
| 23 | +#define AIRTIME_ACTIVE_DURATION (HZ / 10) |
| 24 | + |
| 25 | struct ieee80211_bss { |
| 26 | u32 device_ts_beacon, device_ts_presp; |
| 27 | |
| 28 | --- a/net/mac80211/sta_info.h |
| 29 | +++ b/net/mac80211/sta_info.h |
| 30 | @@ -138,6 +138,7 @@ enum ieee80211_agg_stop_reason { |
| 31 | struct airtime_info { |
| 32 | u64 rx_airtime; |
| 33 | u64 tx_airtime; |
| 34 | + u32 last_active; |
| 35 | s32 deficit; |
| 36 | atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ |
| 37 | u32 aql_limit_low; |
| 38 | --- a/net/mac80211/tx.c |
| 39 | +++ b/net/mac80211/tx.c |
| 40 | @@ -3824,6 +3824,36 @@ static inline s32 ieee80211_sta_deficit( |
| 41 | return air_info->deficit - atomic_read(&air_info->aql_tx_pending); |
| 42 | } |
| 43 | |
| 44 | +static void |
| 45 | +ieee80211_txq_set_active(struct txq_info *txqi) |
| 46 | +{ |
| 47 | + struct sta_info *sta; |
| 48 | + |
| 49 | + if (!txqi->txq.sta) |
| 50 | + return; |
| 51 | + |
| 52 | + sta = container_of(txqi->txq.sta, struct sta_info, sta); |
| 53 | + sta->airtime[txqi->txq.ac].last_active = (u32)jiffies; |
| 54 | +} |
| 55 | + |
| 56 | +static bool |
| 57 | +ieee80211_txq_keep_active(struct txq_info *txqi) |
| 58 | +{ |
| 59 | + struct sta_info *sta; |
| 60 | + u32 diff; |
| 61 | + |
| 62 | + if (!txqi->txq.sta) |
| 63 | + return false; |
| 64 | + |
| 65 | + sta = container_of(txqi->txq.sta, struct sta_info, sta); |
| 66 | + if (ieee80211_sta_deficit(sta, txqi->txq.ac) >= 0) |
| 67 | + return false; |
| 68 | + |
| 69 | + diff = (u32)jiffies - sta->airtime[txqi->txq.ac].last_active; |
| 70 | + |
| 71 | + return diff <= AIRTIME_ACTIVE_DURATION; |
| 72 | +} |
| 73 | + |
| 74 | struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) |
| 75 | { |
| 76 | struct ieee80211_local *local = hw_to_local(hw); |
| 77 | @@ -3870,7 +3900,6 @@ struct ieee80211_txq *ieee80211_next_txq |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | - |
| 82 | if (txqi->schedule_round == local->schedule_round[ac]) |
| 83 | goto out; |
| 84 | |
| 85 | @@ -3890,12 +3919,13 @@ void __ieee80211_schedule_txq(struct iee |
| 86 | { |
| 87 | struct ieee80211_local *local = hw_to_local(hw); |
| 88 | struct txq_info *txqi = to_txq_info(txq); |
| 89 | + bool has_queue; |
| 90 | |
| 91 | spin_lock_bh(&local->active_txq_lock[txq->ac]); |
| 92 | |
| 93 | + has_queue = force || txq_has_queue(txq); |
| 94 | if (list_empty(&txqi->schedule_order) && |
| 95 | - (force || !skb_queue_empty(&txqi->frags) || |
| 96 | - txqi->tin.backlog_packets)) { |
| 97 | + (has_queue || ieee80211_txq_keep_active(txqi))) { |
| 98 | /* If airtime accounting is active, always enqueue STAs at the |
| 99 | * head of the list to ensure that they only get moved to the |
| 100 | * back by the airtime DRR scheduler once they have a negative |
| 101 | @@ -3903,7 +3933,7 @@ void __ieee80211_schedule_txq(struct iee |
| 102 | * get immediately moved to the back of the list on the next |
| 103 | * call to ieee80211_next_txq(). |
| 104 | */ |
| 105 | - if (txqi->txq.sta && local->airtime_flags && |
| 106 | + if (txqi->txq.sta && local->airtime_flags && has_queue && |
| 107 | wiphy_ext_feature_isset(local->hw.wiphy, |
| 108 | NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) |
| 109 | list_add(&txqi->schedule_order, |
| 110 | @@ -3911,6 +3941,8 @@ void __ieee80211_schedule_txq(struct iee |
| 111 | else |
| 112 | list_add_tail(&txqi->schedule_order, |
| 113 | &local->active_txqs[txq->ac]); |
| 114 | + if (has_queue) |
| 115 | + ieee80211_txq_set_active(txqi); |
| 116 | } |
| 117 | |
| 118 | spin_unlock_bh(&local->active_txq_lock[txq->ac]); |