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
5 Content-Type: text/plain; charset=UTF-8
6 Content-Transfer-Encoding: 8bit
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.
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).
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.
21 This effectively disables AQL for iwlwifi, where it fixes a number of
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!)
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>
33 --- a/drivers/net/wireless/ath/ath10k/mac.c
34 +++ b/drivers/net/wireless/ath/ath10k/mac.c
35 @@ -8870,6 +8870,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);
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).
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.
53 * @NUM_NL80211_EXT_FEATURES: number of extended features.
54 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
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,
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];
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]);
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]);
89 + rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
94 +static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
95 + size_t count, loff_t *ppos)
97 + struct sta_info *sta = file->private_data;
98 + struct ieee80211_local *local = sta->sdata->local;
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]);
111 +STA_OPS_RW(airtime);
113 +static ssize_t sta_aql_read(struct file *file, char __user *userbuf,
114 + size_t count, loff_t *ppos)
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];
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
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
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)
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;
159 @@ -251,7 +294,7 @@ static ssize_t sta_airtime_write(struct
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)
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;
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]);
182 -STA_OPS_RW(airtime);
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);
192 + if (wiphy_ext_feature_isset(local->hw.wiphy,
193 + NL80211_EXT_FEATURE_AQL))
196 if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
197 debugfs_create_x32("driver_buffered_tids", 0400,
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;
205 - local->airtime_flags = AIRTIME_USE_TX |
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);
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
218 + if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
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)
232 struct airtime_info {
234 --- a/net/mac80211/tx.c
235 +++ b/net/mac80211/tx.c
236 @@ -3667,7 +3667,7 @@ begin:
238 IEEE80211_SKB_CB(skb)->control.vif = vif;
240 - if (local->airtime_flags & AIRTIME_USE_AQL) {
241 + if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
244 airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
245 @@ -3789,7 +3789,7 @@ bool ieee80211_txq_airtime_check(struct
246 struct sta_info *sta;
247 struct ieee80211_local *local = hw_to_local(hw);
249 - if (!(local->airtime_flags & AIRTIME_USE_AQL))
250 + if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))