mac80211: backport airtime queue limits support
[openwrt/staging/wigyori.git] / package / kernel / mac80211 / patches / subsys / 313-mac80211-Turn-AQL-into-an-NL80211_EXT_FEATURE.patch
1 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
2 Date: Thu, 12 Dec 2019 12:14:37 +0100
3 Subject: [PATCH] mac80211: Turn AQL into an NL80211_EXT_FEATURE
4 MIME-Version: 1.0
5 Content-Type: text/plain; charset=UTF-8
6 Content-Transfer-Encoding: 8bit
7
8 Instead of just having an airtime flag in debugfs, turn AQL into a proper
9 NL80211_EXT_FEATURE, so drivers can turn it on when they are ready, and so
10 we also expose the presence of the feature to userspace.
11
12 This also has the effect of flipping the default, so drivers have to opt in
13 to using AQL instead of getting it by default with TXQs. To keep
14 functionality the same as pre-patch, we set this feature for ath10k (which
15 is where it is needed the most).
16
17 While we're at it, split out the debugfs interface so AQL gets its own
18 per-station debugfs file instead of using the 'airtime' file.
19
20 [Johannes:]
21 This effectively disables AQL for iwlwifi, where it fixes a number of
22 issues:
23 * TSO in iwlwifi is causing underflows and associated warnings in AQL
24 * HE (802.11ax) rates aren't reported properly so at HE rates, AQL could
25 never have a valid estimate (it'd use 6 Mbps instead of up to 2400!)
26
27 Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
28 Link: https://lore.kernel.org/r/20191212111437.224294-1-toke@redhat.com
29 Fixes: 3ace10f5b5ad ("mac80211: Implement Airtime-based Queue Limit (AQL)")
30 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
31 ---
32
33 --- a/drivers/net/wireless/ath/ath10k/mac.c
34 +++ b/drivers/net/wireless/ath/ath10k/mac.c
35 @@ -8868,6 +8868,7 @@ int ath10k_mac_register(struct ath10k *a
36 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
37 wiphy_ext_feature_set(ar->hw->wiphy,
38 NL80211_EXT_FEATURE_SET_SCAN_DWELL);
39 + wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_AQL);
40
41 if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) ||
42 test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map))
43 --- a/include/uapi/linux/nl80211.h
44 +++ b/include/uapi/linux/nl80211.h
45 @@ -5484,6 +5484,10 @@ enum nl80211_feature_flags {
46 * @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
47 * station mode (SAE password is passed as part of the connect command).
48 *
49 + * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL)
50 + * feature, which prevents bufferbloat by using the expected transmission
51 + * time to limit the amount of data buffered in the hardware.
52 + *
53 * @NUM_NL80211_EXT_FEATURES: number of extended features.
54 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
55 */
56 @@ -5529,6 +5533,8 @@ enum nl80211_ext_feature_index {
57 NL80211_EXT_FEATURE_EXT_KEY_ID,
58 NL80211_EXT_FEATURE_STA_TX_PWR,
59 NL80211_EXT_FEATURE_SAE_OFFLOAD,
60 + NL80211_EXT_FEATURE_VLAN_OFFLOAD,
61 + NL80211_EXT_FEATURE_AQL,
62
63 /* add new features before the definition below */
64 NUM_NL80211_EXT_FEATURES,
65 --- a/net/mac80211/debugfs_sta.c
66 +++ b/net/mac80211/debugfs_sta.c
67 @@ -201,8 +201,6 @@ static ssize_t sta_airtime_read(struct f
68 char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
69 u64 rx_airtime = 0, tx_airtime = 0;
70 s64 deficit[IEEE80211_NUM_ACS];
71 - u32 q_depth[IEEE80211_NUM_ACS];
72 - u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS];
73 ssize_t rv;
74 int ac;
75
76 @@ -214,6 +212,56 @@ static ssize_t sta_airtime_read(struct f
77 rx_airtime += sta->airtime[ac].rx_airtime;
78 tx_airtime += sta->airtime[ac].tx_airtime;
79 deficit[ac] = sta->airtime[ac].deficit;
80 + spin_unlock_bh(&local->active_txq_lock[ac]);
81 + }
82 +
83 + p += scnprintf(p, bufsz + buf - p,
84 + "RX: %llu us\nTX: %llu us\nWeight: %u\n"
85 + "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
86 + rx_airtime, tx_airtime, sta->airtime_weight,
87 + deficit[0], deficit[1], deficit[2], deficit[3]);
88 +
89 + rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
90 + kfree(buf);
91 + return rv;
92 +}
93 +
94 +static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
95 + size_t count, loff_t *ppos)
96 +{
97 + struct sta_info *sta = file->private_data;
98 + struct ieee80211_local *local = sta->sdata->local;
99 + int ac;
100 +
101 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
102 + spin_lock_bh(&local->active_txq_lock[ac]);
103 + sta->airtime[ac].rx_airtime = 0;
104 + sta->airtime[ac].tx_airtime = 0;
105 + sta->airtime[ac].deficit = sta->airtime_weight;
106 + spin_unlock_bh(&local->active_txq_lock[ac]);
107 + }
108 +
109 + return count;
110 +}
111 +STA_OPS_RW(airtime);
112 +
113 +static ssize_t sta_aql_read(struct file *file, char __user *userbuf,
114 + size_t count, loff_t *ppos)
115 +{
116 + struct sta_info *sta = file->private_data;
117 + struct ieee80211_local *local = sta->sdata->local;
118 + size_t bufsz = 400;
119 + char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
120 + u32 q_depth[IEEE80211_NUM_ACS];
121 + u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS];
122 + ssize_t rv;
123 + int ac;
124 +
125 + if (!buf)
126 + return -ENOMEM;
127 +
128 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
129 + spin_lock_bh(&local->active_txq_lock[ac]);
130 q_limit_l[ac] = sta->airtime[ac].aql_limit_low;
131 q_limit_h[ac] = sta->airtime[ac].aql_limit_high;
132 spin_unlock_bh(&local->active_txq_lock[ac]);
133 @@ -221,12 +269,8 @@ static ssize_t sta_airtime_read(struct f
134 }
135
136 p += scnprintf(p, bufsz + buf - p,
137 - "RX: %llu us\nTX: %llu us\nWeight: %u\n"
138 - "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n"
139 "Q depth: VO: %u us VI: %u us BE: %u us BK: %u us\n"
140 "Q limit[low/high]: VO: %u/%u VI: %u/%u BE: %u/%u BK: %u/%u\n",
141 - rx_airtime, tx_airtime, sta->airtime_weight,
142 - deficit[0], deficit[1], deficit[2], deficit[3],
143 q_depth[0], q_depth[1], q_depth[2], q_depth[3],
144 q_limit_l[0], q_limit_h[0], q_limit_l[1], q_limit_h[1],
145 q_limit_l[2], q_limit_h[2], q_limit_l[3], q_limit_h[3]),
146 @@ -236,11 +280,10 @@ static ssize_t sta_airtime_read(struct f
147 return rv;
148 }
149
150 -static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
151 +static ssize_t sta_aql_write(struct file *file, const char __user *userbuf,
152 size_t count, loff_t *ppos)
153 {
154 struct sta_info *sta = file->private_data;
155 - struct ieee80211_local *local = sta->sdata->local;
156 u32 ac, q_limit_l, q_limit_h;
157 char _buf[100] = {}, *buf = _buf;
158
159 @@ -251,7 +294,7 @@ static ssize_t sta_airtime_write(struct
160 return -EFAULT;
161
162 buf[sizeof(_buf) - 1] = '\0';
163 - if (sscanf(buf, "queue limit %u %u %u", &ac, &q_limit_l, &q_limit_h)
164 + if (sscanf(buf, "limit %u %u %u", &ac, &q_limit_l, &q_limit_h)
165 != 3)
166 return -EINVAL;
167
168 @@ -261,17 +304,10 @@ static ssize_t sta_airtime_write(struct
169 sta->airtime[ac].aql_limit_low = q_limit_l;
170 sta->airtime[ac].aql_limit_high = q_limit_h;
171
172 - for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
173 - spin_lock_bh(&local->active_txq_lock[ac]);
174 - sta->airtime[ac].rx_airtime = 0;
175 - sta->airtime[ac].tx_airtime = 0;
176 - sta->airtime[ac].deficit = sta->airtime_weight;
177 - spin_unlock_bh(&local->active_txq_lock[ac]);
178 - }
179 -
180 return count;
181 }
182 -STA_OPS_RW(airtime);
183 +STA_OPS_RW(aql);
184 +
185
186 static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
187 size_t count, loff_t *ppos)
188 @@ -1001,6 +1037,10 @@ void ieee80211_sta_debugfs_add(struct st
189 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
190 DEBUGFS_ADD(airtime);
191
192 + if (wiphy_ext_feature_isset(local->hw.wiphy,
193 + NL80211_EXT_FEATURE_AQL))
194 + DEBUGFS_ADD(aql);
195 +
196 if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
197 debugfs_create_x32("driver_buffered_tids", 0400,
198 sta->debugfs_dir,
199 --- a/net/mac80211/main.c
200 +++ b/net/mac80211/main.c
201 @@ -674,9 +674,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
202 IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H;
203 }
204
205 - local->airtime_flags = AIRTIME_USE_TX |
206 - AIRTIME_USE_RX |
207 - AIRTIME_USE_AQL;
208 + local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
209 local->aql_threshold = IEEE80211_AQL_THRESHOLD;
210 atomic_set(&local->aql_total_pending_airtime, 0);
211
212 --- a/net/mac80211/sta_info.c
213 +++ b/net/mac80211/sta_info.c
214 @@ -1917,6 +1917,9 @@ void ieee80211_sta_update_pending_airtim
215 {
216 int tx_pending;
217
218 + if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
219 + return;
220 +
221 if (!tx_completed) {
222 if (sta)
223 atomic_add(tx_airtime,
224 --- a/net/mac80211/sta_info.h
225 +++ b/net/mac80211/sta_info.h
226 @@ -127,7 +127,6 @@ enum ieee80211_agg_stop_reason {
227 /* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */
228 #define AIRTIME_USE_TX BIT(0)
229 #define AIRTIME_USE_RX BIT(1)
230 -#define AIRTIME_USE_AQL BIT(2)
231
232 struct airtime_info {
233 u64 rx_airtime;
234 --- a/net/mac80211/tx.c
235 +++ b/net/mac80211/tx.c
236 @@ -3658,7 +3658,7 @@ begin:
237
238 IEEE80211_SKB_CB(skb)->control.vif = vif;
239
240 - if (local->airtime_flags & AIRTIME_USE_AQL) {
241 + if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
242 u32 airtime;
243
244 airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
245 @@ -3780,7 +3780,7 @@ bool ieee80211_txq_airtime_check(struct
246 struct sta_info *sta;
247 struct ieee80211_local *local = hw_to_local(hw);
248
249 - if (!(local->airtime_flags & AIRTIME_USE_AQL))
250 + if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
251 return true;
252
253 if (!txq->sta)