389f2ae225ebeffe1447b88420fed6617e4ba529
[oweals/openwrt.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 @@ -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);
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 @@ -202,8 +202,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 @@ -215,6 +213,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 @@ -222,12 +270,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 @@ -237,11 +281,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 @@ -252,7 +295,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 @@ -262,17 +305,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 @@ -1002,6 +1038,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 @@ -1922,6 +1922,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 @@ -128,7 +128,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 @@ -3691,7 +3691,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 @@ -3813,7 +3813,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)