mac80211: fix a regression in the broadcast AQL patch
[openwrt/staging/nbd.git] / package / kernel / mac80211 / patches / subsys / 330-mac80211-add-AQL-support-for-broadcast-packets.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Fri, 9 Feb 2024 19:43:40 +0100
3 Subject: [PATCH] mac80211: add AQL support for broadcast packets
4
5 Excessive broadcast traffic with little competing unicast traffic can easily
6 flood hardware queues, leading to throughput issues. Additionally, filling
7 the hardware queues with too many packets breaks FQ for broadcast data.
8 Fix this by enabling AQL for broadcast packets.
9
10 Signed-off-by: Felix Fietkau <nbd@nbd.name>
11 ---
12
13 --- a/include/net/cfg80211.h
14 +++ b/include/net/cfg80211.h
15 @@ -3324,6 +3324,7 @@ enum wiphy_params_flags {
16 /* The per TXQ device queue limit in airtime */
17 #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 5000
18 #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 12000
19 +#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC 50000
20
21 /* The per interface airtime threshold to switch to lower queue limit */
22 #define IEEE80211_AQL_THRESHOLD 24000
23 --- a/net/mac80211/debugfs.c
24 +++ b/net/mac80211/debugfs.c
25 @@ -215,11 +215,13 @@ static ssize_t aql_pending_read(struct f
26 "VI %u us\n"
27 "BE %u us\n"
28 "BK %u us\n"
29 + "BC/MC %u us\n"
30 "total %u us\n",
31 atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VO]),
32 atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VI]),
33 atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BE]),
34 atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BK]),
35 + atomic_read(&local->aql_bc_pending_airtime),
36 atomic_read(&local->aql_total_pending_airtime));
37 return simple_read_from_buffer(user_buf, count, ppos,
38 buf, len);
39 @@ -245,7 +247,8 @@ static ssize_t aql_txq_limit_read(struct
40 "VO %u %u\n"
41 "VI %u %u\n"
42 "BE %u %u\n"
43 - "BK %u %u\n",
44 + "BK %u %u\n"
45 + "BC/MC %u\n",
46 local->aql_txq_limit_low[IEEE80211_AC_VO],
47 local->aql_txq_limit_high[IEEE80211_AC_VO],
48 local->aql_txq_limit_low[IEEE80211_AC_VI],
49 @@ -253,7 +256,8 @@ static ssize_t aql_txq_limit_read(struct
50 local->aql_txq_limit_low[IEEE80211_AC_BE],
51 local->aql_txq_limit_high[IEEE80211_AC_BE],
52 local->aql_txq_limit_low[IEEE80211_AC_BK],
53 - local->aql_txq_limit_high[IEEE80211_AC_BK]);
54 + local->aql_txq_limit_high[IEEE80211_AC_BK],
55 + local->aql_txq_limit_bc);
56 return simple_read_from_buffer(user_buf, count, ppos,
57 buf, len);
58 }
59 @@ -279,6 +283,11 @@ static ssize_t aql_txq_limit_write(struc
60 else
61 buf[count] = '\0';
62
63 + if (sscanf(buf, "mcast %u", &q_limit_low) == 1) {
64 + local->aql_txq_limit_bc = q_limit_low;
65 + return count;
66 + }
67 +
68 if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
69 return -EINVAL;
70
71 --- a/net/mac80211/ieee80211_i.h
72 +++ b/net/mac80211/ieee80211_i.h
73 @@ -1328,10 +1328,12 @@ struct ieee80211_local {
74 spinlock_t handle_wake_tx_queue_lock;
75
76 u16 airtime_flags;
77 + u32 aql_txq_limit_bc;
78 u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
79 u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
80 u32 aql_threshold;
81 atomic_t aql_total_pending_airtime;
82 + atomic_t aql_bc_pending_airtime;
83 atomic_t aql_ac_pending_airtime[IEEE80211_NUM_ACS];
84
85 const struct ieee80211_ops *ops;
86 --- a/net/mac80211/main.c
87 +++ b/net/mac80211/main.c
88 @@ -788,6 +788,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
89 spin_lock_init(&local->rx_path_lock);
90 spin_lock_init(&local->queue_stop_reason_lock);
91
92 + local->aql_txq_limit_bc = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC;
93 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
94 INIT_LIST_HEAD(&local->active_txqs[i]);
95 spin_lock_init(&local->active_txq_lock[i]);
96 --- a/net/mac80211/sta_info.c
97 +++ b/net/mac80211/sta_info.c
98 @@ -2341,29 +2341,33 @@ void ieee80211_sta_update_pending_airtim
99 struct sta_info *sta, u8 ac,
100 u16 tx_airtime, bool tx_completed)
101 {
102 - int tx_pending;
103 + int tx_pending = 0;
104 + atomic_t *counter;
105
106 if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
107 return;
108
109 - if (!tx_completed) {
110 - if (sta)
111 - atomic_add(tx_airtime,
112 - &sta->airtime[ac].aql_tx_pending);
113 + if (sta)
114 + counter = &sta->airtime[ac].aql_tx_pending;
115 + else
116 + counter = &local->aql_bc_pending_airtime;
117 +
118 + if (!tx_completed)
119 + atomic_add(tx_airtime, counter);
120 + else
121 + tx_pending = atomic_sub_return(tx_airtime, counter);
122 + if (tx_pending < 0)
123 + atomic_cmpxchg(counter, tx_pending, 0);
124 +
125 + if (!sta)
126 + return;
127
128 + if (!tx_completed) {
129 atomic_add(tx_airtime, &local->aql_total_pending_airtime);
130 atomic_add(tx_airtime, &local->aql_ac_pending_airtime[ac]);
131 return;
132 }
133
134 - if (sta) {
135 - tx_pending = atomic_sub_return(tx_airtime,
136 - &sta->airtime[ac].aql_tx_pending);
137 - if (tx_pending < 0)
138 - atomic_cmpxchg(&sta->airtime[ac].aql_tx_pending,
139 - tx_pending, 0);
140 - }
141 -
142 atomic_sub(tx_airtime, &local->aql_total_pending_airtime);
143 tx_pending = atomic_sub_return(tx_airtime,
144 &local->aql_ac_pending_airtime[ac]);
145 --- a/net/mac80211/tx.c
146 +++ b/net/mac80211/tx.c
147 @@ -3958,9 +3958,8 @@ begin:
148 encap_out:
149 IEEE80211_SKB_CB(skb)->control.vif = vif;
150
151 - if (tx.sta &&
152 - wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
153 - bool ampdu = txq->ac != IEEE80211_AC_VO;
154 + if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
155 + bool ampdu = txq->sta && txq->ac != IEEE80211_AC_VO;
156 u32 airtime;
157
158 airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
159 @@ -4026,6 +4025,7 @@ struct ieee80211_txq *ieee80211_next_txq
160 struct ieee80211_txq *ret = NULL;
161 struct txq_info *txqi = NULL, *head = NULL;
162 bool found_eligible_txq = false;
163 + bool aql_check;
164
165 spin_lock_bh(&local->active_txq_lock[ac]);
166
167 @@ -4049,26 +4049,26 @@ struct ieee80211_txq *ieee80211_next_txq
168 if (!head)
169 head = txqi;
170
171 + aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
172 + if (aql_check)
173 + found_eligible_txq = true;
174 +
175 if (txqi->txq.sta) {
176 struct sta_info *sta = container_of(txqi->txq.sta,
177 struct sta_info, sta);
178 - bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
179 - s32 deficit = ieee80211_sta_deficit(sta, txqi->txq.ac);
180 -
181 - if (aql_check)
182 - found_eligible_txq = true;
183 -
184 - if (deficit < 0)
185 + if (ieee80211_sta_deficit(sta, txqi->txq.ac) < 0) {
186 sta->airtime[txqi->txq.ac].deficit +=
187 sta->airtime_weight << AIRTIME_QUANTUM_SHIFT;
188 -
189 - if (deficit < 0 || !aql_check) {
190 - list_move_tail(&txqi->schedule_order,
191 - &local->active_txqs[txqi->txq.ac]);
192 - goto begin;
193 + aql_check = false;
194 }
195 }
196
197 + if (!aql_check) {
198 + list_move_tail(&txqi->schedule_order,
199 + &local->active_txqs[txqi->txq.ac]);
200 + goto begin;
201 + }
202 +
203 if (txqi->schedule_round == local->schedule_round[ac])
204 goto out;
205
206 @@ -4133,7 +4133,8 @@ bool ieee80211_txq_airtime_check(struct
207 return true;
208
209 if (!txq->sta)
210 - return true;
211 + return atomic_read(&local->aql_bc_pending_airtime) <
212 + local->aql_txq_limit_bc;
213
214 if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
215 return true;
216 @@ -4182,15 +4183,15 @@ bool ieee80211_txq_may_transmit(struct i
217
218 spin_lock_bh(&local->active_txq_lock[ac]);
219
220 - if (!txqi->txq.sta)
221 - goto out;
222 -
223 if (list_empty(&txqi->schedule_order))
224 goto out;
225
226 if (!ieee80211_txq_schedule_airtime_check(local, ac))
227 goto out;
228
229 + if (!txqi->txq.sta)
230 + goto out;
231 +
232 list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
233 schedule_order) {
234 if (iter == txqi)