aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-02-25 04:03:25 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-02-28 15:31:11 -0500
commitabfbc3af57b1b92ff976ce7f1c776c169d14ed8a (patch)
tree43e22cfdcdda1c832350f031460418972f226866 /net
parent31f909a2c0abfc1a1a76b2981d28ac85d33210e7 (diff)
mac80211: remove TX latency measurement code
Revert commit ad38bfc916da ("mac80211: Tx frame latency statistics") (along with some follow-up fixes). This code turned out not to be as useful in the current form as we thought, and we've internally hacked it up more, but that's not very suitable for upstream (for now), and we might just do that with tracing instead. Therefore, for now at least, remove this code. We might also need to use the skb->tstamp field for the TCP performance issue, which is more important than the debugging. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/debugfs.c168
-rw-r--r--net/mac80211/debugfs_sta.c134
-rw-r--r--net/mac80211/ieee80211_i.h24
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/sta_info.c54
-rw-r--r--net/mac80211/sta_info.h22
-rw-r--r--net/mac80211/status.c74
-rw-r--r--net/mac80211/tx.c22
8 files changed, 5 insertions, 495 deletions
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index eeb0bbd69d98..74830ce25e74 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -18,172 +18,6 @@
18 18
19#define DEBUGFS_FORMAT_BUFFER_SIZE 100 19#define DEBUGFS_FORMAT_BUFFER_SIZE 100
20 20
21#define TX_LATENCY_BIN_DELIMTER_C ','
22#define TX_LATENCY_BIN_DELIMTER_S ","
23#define TX_LATENCY_BINS_DISABLED "enable(bins disabled)\n"
24#define TX_LATENCY_DISABLED "disable\n"
25
26
27/*
28 * Display if Tx latency statistics & bins are enabled/disabled
29 */
30static ssize_t sta_tx_latency_stat_read(struct file *file,
31 char __user *userbuf,
32 size_t count, loff_t *ppos)
33{
34 struct ieee80211_local *local = file->private_data;
35 struct ieee80211_tx_latency_bin_ranges *tx_latency;
36 char *buf;
37 int bufsz, i, ret;
38 int pos = 0;
39
40 rcu_read_lock();
41
42 tx_latency = rcu_dereference(local->tx_latency);
43
44 if (tx_latency && tx_latency->n_ranges) {
45 bufsz = tx_latency->n_ranges * 15;
46 buf = kzalloc(bufsz, GFP_ATOMIC);
47 if (!buf)
48 goto err;
49
50 for (i = 0; i < tx_latency->n_ranges; i++)
51 pos += scnprintf(buf + pos, bufsz - pos, "%d,",
52 tx_latency->ranges[i]);
53 pos += scnprintf(buf + pos, bufsz - pos, "\n");
54 } else if (tx_latency) {
55 bufsz = sizeof(TX_LATENCY_BINS_DISABLED) + 1;
56 buf = kzalloc(bufsz, GFP_ATOMIC);
57 if (!buf)
58 goto err;
59
60 pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
61 TX_LATENCY_BINS_DISABLED);
62 } else {
63 bufsz = sizeof(TX_LATENCY_DISABLED) + 1;
64 buf = kzalloc(bufsz, GFP_ATOMIC);
65 if (!buf)
66 goto err;
67
68 pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
69 TX_LATENCY_DISABLED);
70 }
71
72 rcu_read_unlock();
73
74 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
75 kfree(buf);
76
77 return ret;
78err:
79 rcu_read_unlock();
80 return -ENOMEM;
81}
82
83/*
84 * Receive input from user regarding Tx latency statistics
85 * The input should indicate if Tx latency statistics and bins are
86 * enabled/disabled.
87 * If bins are enabled input should indicate the amount of different bins and
88 * their ranges. Each bin will count how many Tx frames transmitted within the
89 * appropriate latency.
90 * Legal input is:
91 * a) "enable(bins disabled)" - to enable only general statistics
92 * b) "a,b,c,d,...z" - to enable general statistics and bins, where all are
93 * numbers and a < b < c < d.. < z
94 * c) "disable" - disable all statistics
95 * NOTE: must configure Tx latency statistics bins before stations connected.
96 */
97
98static ssize_t sta_tx_latency_stat_write(struct file *file,
99 const char __user *userbuf,
100 size_t count, loff_t *ppos)
101{
102 struct ieee80211_local *local = file->private_data;
103 char buf[128] = {};
104 char *bins = buf;
105 char *token;
106 int buf_size, i, alloc_size;
107 int prev_bin = 0;
108 int n_ranges = 0;
109 int ret = count;
110 struct ieee80211_tx_latency_bin_ranges *tx_latency;
111
112 if (sizeof(buf) <= count)
113 return -EINVAL;
114 buf_size = count;
115 if (copy_from_user(buf, userbuf, buf_size))
116 return -EFAULT;
117
118 mutex_lock(&local->sta_mtx);
119
120 /* cannot change config once we have stations */
121 if (local->num_sta)
122 goto unlock;
123
124 tx_latency =
125 rcu_dereference_protected(local->tx_latency,
126 lockdep_is_held(&local->sta_mtx));
127
128 /* disable Tx statistics */
129 if (!strcmp(buf, TX_LATENCY_DISABLED)) {
130 if (!tx_latency)
131 goto unlock;
132 RCU_INIT_POINTER(local->tx_latency, NULL);
133 synchronize_rcu();
134 kfree(tx_latency);
135 goto unlock;
136 }
137
138 /* Tx latency already enabled */
139 if (tx_latency)
140 goto unlock;
141
142 if (strcmp(TX_LATENCY_BINS_DISABLED, buf)) {
143 /* check how many bins and between what ranges user requested */
144 token = buf;
145 while (*token != '\0') {
146 if (*token == TX_LATENCY_BIN_DELIMTER_C)
147 n_ranges++;
148 token++;
149 }
150 n_ranges++;
151 }
152
153 alloc_size = sizeof(struct ieee80211_tx_latency_bin_ranges) +
154 n_ranges * sizeof(u32);
155 tx_latency = kzalloc(alloc_size, GFP_ATOMIC);
156 if (!tx_latency) {
157 ret = -ENOMEM;
158 goto unlock;
159 }
160 tx_latency->n_ranges = n_ranges;
161 for (i = 0; i < n_ranges; i++) { /* setting bin ranges */
162 token = strsep(&bins, TX_LATENCY_BIN_DELIMTER_S);
163 sscanf(token, "%d", &tx_latency->ranges[i]);
164 /* bins values should be in ascending order */
165 if (prev_bin >= tx_latency->ranges[i]) {
166 ret = -EINVAL;
167 kfree(tx_latency);
168 goto unlock;
169 }
170 prev_bin = tx_latency->ranges[i];
171 }
172 rcu_assign_pointer(local->tx_latency, tx_latency);
173
174unlock:
175 mutex_unlock(&local->sta_mtx);
176
177 return ret;
178}
179
180static const struct file_operations stats_tx_latency_ops = {
181 .write = sta_tx_latency_stat_write,
182 .read = sta_tx_latency_stat_read,
183 .open = simple_open,
184 .llseek = generic_file_llseek,
185};
186
187int mac80211_format_buffer(char __user *userbuf, size_t count, 21int mac80211_format_buffer(char __user *userbuf, size_t count,
188 loff_t *ppos, char *fmt, ...) 22 loff_t *ppos, char *fmt, ...)
189{ 23{
@@ -475,6 +309,4 @@ void debugfs_hw_add(struct ieee80211_local *local)
475 DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount); 309 DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
476 DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount); 310 DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
477 DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount); 311 DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
478
479 DEBUGFS_DEVSTATS_ADD(tx_latency);
480} 312}
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 94c70091bbd7..252859e90e8a 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -39,13 +39,6 @@ static const struct file_operations sta_ ##name## _ops = { \
39 .llseek = generic_file_llseek, \ 39 .llseek = generic_file_llseek, \
40} 40}
41 41
42#define STA_OPS_W(name) \
43static const struct file_operations sta_ ##name## _ops = { \
44 .write = sta_##name##_write, \
45 .open = simple_open, \
46 .llseek = generic_file_llseek, \
47}
48
49#define STA_OPS_RW(name) \ 42#define STA_OPS_RW(name) \
50static const struct file_operations sta_ ##name## _ops = { \ 43static const struct file_operations sta_ ##name## _ops = { \
51 .read = sta_##name##_read, \ 44 .read = sta_##name##_read, \
@@ -398,131 +391,6 @@ static ssize_t sta_last_rx_rate_read(struct file *file, char __user *userbuf,
398} 391}
399STA_OPS(last_rx_rate); 392STA_OPS(last_rx_rate);
400 393
401static int
402sta_tx_latency_stat_header(struct ieee80211_tx_latency_bin_ranges *tx_latency,
403 char *buf, int pos, int bufsz)
404{
405 int i;
406 int range_count = tx_latency->n_ranges;
407 u32 *bin_ranges = tx_latency->ranges;
408
409 pos += scnprintf(buf + pos, bufsz - pos,
410 "Station\t\t\tTID\tMax\tAvg");
411 if (range_count) {
412 pos += scnprintf(buf + pos, bufsz - pos,
413 "\t<=%d", bin_ranges[0]);
414 for (i = 0; i < range_count - 1; i++)
415 pos += scnprintf(buf + pos, bufsz - pos, "\t%d-%d",
416 bin_ranges[i], bin_ranges[i+1]);
417 pos += scnprintf(buf + pos, bufsz - pos,
418 "\t%d<", bin_ranges[range_count - 1]);
419 }
420
421 pos += scnprintf(buf + pos, bufsz - pos, "\n");
422
423 return pos;
424}
425
426static int
427sta_tx_latency_stat_table(struct ieee80211_tx_latency_bin_ranges *tx_lat_range,
428 struct ieee80211_tx_latency_stat *tx_lat,
429 char *buf, int pos, int bufsz, int tid)
430{
431 u32 avg = 0;
432 int j;
433 int bin_count = tx_lat->bin_count;
434
435 pos += scnprintf(buf + pos, bufsz - pos, "\t\t\t%d", tid);
436 /* make sure you don't divide in 0 */
437 if (tx_lat->counter)
438 avg = tx_lat->sum / tx_lat->counter;
439
440 pos += scnprintf(buf + pos, bufsz - pos, "\t%d\t%d",
441 tx_lat->max, avg);
442
443 if (tx_lat_range->n_ranges && tx_lat->bins)
444 for (j = 0; j < bin_count; j++)
445 pos += scnprintf(buf + pos, bufsz - pos,
446 "\t%d", tx_lat->bins[j]);
447 pos += scnprintf(buf + pos, bufsz - pos, "\n");
448
449 return pos;
450}
451
452/*
453 * Output Tx latency statistics station && restart all statistics information
454 */
455static ssize_t sta_tx_latency_stat_read(struct file *file,
456 char __user *userbuf,
457 size_t count, loff_t *ppos)
458{
459 struct sta_info *sta = file->private_data;
460 struct ieee80211_local *local = sta->local;
461 struct ieee80211_tx_latency_bin_ranges *tx_latency;
462 char *buf;
463 int bufsz, ret, i;
464 int pos = 0;
465
466 bufsz = 20 * IEEE80211_NUM_TIDS *
467 sizeof(struct ieee80211_tx_latency_stat);
468 buf = kzalloc(bufsz, GFP_KERNEL);
469 if (!buf)
470 return -ENOMEM;
471
472 rcu_read_lock();
473
474 tx_latency = rcu_dereference(local->tx_latency);
475
476 if (!sta->tx_lat) {
477 pos += scnprintf(buf + pos, bufsz - pos,
478 "Tx latency statistics are not enabled\n");
479 goto unlock;
480 }
481
482 pos = sta_tx_latency_stat_header(tx_latency, buf, pos, bufsz);
483
484 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", sta->sta.addr);
485 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
486 pos = sta_tx_latency_stat_table(tx_latency, &sta->tx_lat[i],
487 buf, pos, bufsz, i);
488unlock:
489 rcu_read_unlock();
490
491 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
492 kfree(buf);
493
494 return ret;
495}
496STA_OPS(tx_latency_stat);
497
498static ssize_t sta_tx_latency_stat_reset_write(struct file *file,
499 const char __user *userbuf,
500 size_t count, loff_t *ppos)
501{
502 u32 *bins;
503 int bin_count;
504 struct sta_info *sta = file->private_data;
505 int i;
506
507 if (!sta->tx_lat)
508 return -EINVAL;
509
510 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
511 bins = sta->tx_lat[i].bins;
512 bin_count = sta->tx_lat[i].bin_count;
513
514 sta->tx_lat[i].max = 0;
515 sta->tx_lat[i].sum = 0;
516 sta->tx_lat[i].counter = 0;
517
518 if (bin_count)
519 memset(bins, 0, bin_count * sizeof(u32));
520 }
521
522 return count;
523}
524STA_OPS_W(tx_latency_stat_reset);
525
526#define DEBUGFS_ADD(name) \ 394#define DEBUGFS_ADD(name) \
527 debugfs_create_file(#name, 0400, \ 395 debugfs_create_file(#name, 0400, \
528 sta->debugfs.dir, sta, &sta_ ##name## _ops); 396 sta->debugfs.dir, sta, &sta_ ##name## _ops);
@@ -576,8 +444,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
576 DEBUGFS_ADD(last_ack_signal); 444 DEBUGFS_ADD(last_ack_signal);
577 DEBUGFS_ADD(current_tx_rate); 445 DEBUGFS_ADD(current_tx_rate);
578 DEBUGFS_ADD(last_rx_rate); 446 DEBUGFS_ADD(last_rx_rate);
579 DEBUGFS_ADD(tx_latency_stat);
580 DEBUGFS_ADD(tx_latency_stat_reset);
581 447
582 DEBUGFS_ADD_COUNTER(rx_packets, rx_packets); 448 DEBUGFS_ADD_COUNTER(rx_packets, rx_packets);
583 DEBUGFS_ADD_COUNTER(tx_packets, tx_packets); 449 DEBUGFS_ADD_COUNTER(tx_packets, tx_packets);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3afe36824703..2c14447e1f4c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1030,24 +1030,6 @@ struct tpt_led_trigger {
1030}; 1030};
1031#endif 1031#endif
1032 1032
1033/*
1034 * struct ieee80211_tx_latency_bin_ranges - Tx latency statistics bins ranges
1035 *
1036 * Measuring Tx latency statistics. Counts how many Tx frames transmitted in a
1037 * certain latency range (in Milliseconds). Each station that uses these
1038 * ranges will have bins to count the amount of frames received in that range.
1039 * The user can configure the ranges via debugfs.
1040 * If ranges is NULL then Tx latency statistics bins are disabled for all
1041 * stations.
1042 *
1043 * @n_ranges: number of ranges that are taken in account
1044 * @ranges: the ranges that the user requested or NULL if disabled.
1045 */
1046struct ieee80211_tx_latency_bin_ranges {
1047 int n_ranges;
1048 u32 ranges[];
1049};
1050
1051/** 1033/**
1052 * mac80211 scan flags - currently active scan mode 1034 * mac80211 scan flags - currently active scan mode
1053 * 1035 *
@@ -1199,12 +1181,6 @@ struct ieee80211_local {
1199 struct timer_list sta_cleanup; 1181 struct timer_list sta_cleanup;
1200 int sta_generation; 1182 int sta_generation;
1201 1183
1202 /*
1203 * Tx latency statistics parameters for all stations.
1204 * Can enable via debugfs (NULL when disabled).
1205 */
1206 struct ieee80211_tx_latency_bin_ranges __rcu *tx_latency;
1207
1208 struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; 1184 struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
1209 struct tasklet_struct tx_pending_tasklet; 1185 struct tasklet_struct tx_pending_tasklet;
1210 1186
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5e09d354c5a5..2f51e6d1f2b3 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1201,8 +1201,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
1201 ieee80211_free_ack_frame, NULL); 1201 ieee80211_free_ack_frame, NULL);
1202 idr_destroy(&local->ack_status_frames); 1202 idr_destroy(&local->ack_status_frames);
1203 1203
1204 kfree(rcu_access_pointer(local->tx_latency));
1205
1206 sta_info_stop(local); 1204 sta_info_stop(local);
1207 1205
1208 wiphy_free(local->hw.wiphy); 1206 wiphy_free(local->hw.wiphy);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 00ca8dcc2bcf..d94004e7ce37 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -229,17 +229,9 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
229 */ 229 */
230void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) 230void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
231{ 231{
232 int i;
233
234 if (sta->rate_ctrl) 232 if (sta->rate_ctrl)
235 rate_control_free_sta(sta); 233 rate_control_free_sta(sta);
236 234
237 if (sta->tx_lat) {
238 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
239 kfree(sta->tx_lat[i].bins);
240 kfree(sta->tx_lat);
241 }
242
243 sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); 235 sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
244 236
245 kfree(rcu_dereference_raw(sta->sta.rates)); 237 kfree(rcu_dereference_raw(sta->sta.rates));
@@ -295,42 +287,12 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
295 struct ieee80211_local *local = sdata->local; 287 struct ieee80211_local *local = sdata->local;
296 struct sta_info *sta; 288 struct sta_info *sta;
297 struct timespec uptime; 289 struct timespec uptime;
298 struct ieee80211_tx_latency_bin_ranges *tx_latency;
299 int i; 290 int i;
300 291
301 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); 292 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
302 if (!sta) 293 if (!sta)
303 return NULL; 294 return NULL;
304 295
305 rcu_read_lock();
306 tx_latency = rcu_dereference(local->tx_latency);
307 /* init stations Tx latency statistics && TID bins */
308 if (tx_latency) {
309 sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS *
310 sizeof(struct ieee80211_tx_latency_stat),
311 GFP_ATOMIC);
312 if (!sta->tx_lat) {
313 rcu_read_unlock();
314 goto free;
315 }
316
317 if (tx_latency->n_ranges) {
318 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
319 /* size of bins is size of the ranges +1 */
320 sta->tx_lat[i].bin_count =
321 tx_latency->n_ranges + 1;
322 sta->tx_lat[i].bins =
323 kcalloc(sta->tx_lat[i].bin_count,
324 sizeof(u32), GFP_ATOMIC);
325 if (!sta->tx_lat[i].bins) {
326 rcu_read_unlock();
327 goto free;
328 }
329 }
330 }
331 }
332 rcu_read_unlock();
333
334 spin_lock_init(&sta->lock); 296 spin_lock_init(&sta->lock);
335 spin_lock_init(&sta->ps_lock); 297 spin_lock_init(&sta->ps_lock);
336 INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames); 298 INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
@@ -359,8 +321,10 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
359 for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) 321 for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
360 ewma_init(&sta->chain_signal_avg[i], 1024, 8); 322 ewma_init(&sta->chain_signal_avg[i], 1024, 8);
361 323
362 if (sta_prepare_rate_control(local, sta, gfp)) 324 if (sta_prepare_rate_control(local, sta, gfp)) {
363 goto free; 325 kfree(sta);
326 return NULL;
327 }
364 328
365 for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 329 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
366 /* 330 /*
@@ -405,16 +369,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
405 } 369 }
406 370
407 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); 371 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
408 return sta;
409 372
410free: 373 return sta;
411 if (sta->tx_lat) {
412 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
413 kfree(sta->tx_lat[i].bins);
414 kfree(sta->tx_lat);
415 }
416 kfree(sta);
417 return NULL;
418} 374}
419 375
420static int sta_info_insert_check(struct sta_info *sta) 376static int sta_info_insert_check(struct sta_info *sta)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 925e68fe64c7..248f56e59ebc 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -234,25 +234,6 @@ struct sta_ampdu_mlme {
234 u8 dialog_token_allocator; 234 u8 dialog_token_allocator;
235}; 235};
236 236
237/*
238 * struct ieee80211_tx_latency_stat - Tx latency statistics
239 *
240 * Measures TX latency and jitter for a station per TID.
241 *
242 * @max: worst case latency
243 * @sum: sum of all latencies
244 * @counter: amount of Tx frames sent from interface
245 * @bins: each bin counts how many frames transmitted within a certain
246 * latency range. when disabled it is NULL.
247 * @bin_count: amount of bins.
248 */
249struct ieee80211_tx_latency_stat {
250 u32 max;
251 u32 sum;
252 u32 counter;
253 u32 *bins;
254 u32 bin_count;
255};
256 237
257/* Value to indicate no TID reservation */ 238/* Value to indicate no TID reservation */
258#define IEEE80211_TID_UNRESERVED 0xff 239#define IEEE80211_TID_UNRESERVED 0xff
@@ -314,7 +295,6 @@ struct ieee80211_tx_latency_stat {
314 * @tid_seq: per-TID sequence numbers for sending to this STA 295 * @tid_seq: per-TID sequence numbers for sending to this STA
315 * @ampdu_mlme: A-MPDU state machine state 296 * @ampdu_mlme: A-MPDU state machine state
316 * @timer_to_tid: identity mapping to ID timers 297 * @timer_to_tid: identity mapping to ID timers
317 * @tx_lat: Tx latency statistics
318 * @llid: Local link ID 298 * @llid: Local link ID
319 * @plid: Peer link ID 299 * @plid: Peer link ID
320 * @reason: Cancel reason on PLINK_HOLDING state 300 * @reason: Cancel reason on PLINK_HOLDING state
@@ -435,8 +415,6 @@ struct sta_info {
435 struct sta_ampdu_mlme ampdu_mlme; 415 struct sta_ampdu_mlme ampdu_mlme;
436 u8 timer_to_tid[IEEE80211_NUM_TIDS]; 416 u8 timer_to_tid[IEEE80211_NUM_TIDS];
437 417
438 struct ieee80211_tx_latency_stat *tx_lat;
439
440#ifdef CONFIG_MAC80211_MESH 418#ifdef CONFIG_MAC80211_MESH
441 /* 419 /*
442 * Mesh peer link attributes 420 * Mesh peer link attributes
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index e679b7c9b160..2c51742428d5 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -12,7 +12,6 @@
12 12
13#include <linux/export.h> 13#include <linux/export.h>
14#include <linux/etherdevice.h> 14#include <linux/etherdevice.h>
15#include <linux/time.h>
16#include <net/mac80211.h> 15#include <net/mac80211.h>
17#include <asm/unaligned.h> 16#include <asm/unaligned.h>
18#include "ieee80211_i.h" 17#include "ieee80211_i.h"
@@ -515,73 +514,6 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
515} 514}
516 515
517/* 516/*
518 * Measure Tx frame completion and removal time for Tx latency statistics
519 * calculation. A single Tx frame latency should be measured from when it
520 * is entering the Kernel until we receive Tx complete confirmation indication
521 * and remove the skb.
522 */
523static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local,
524 struct sk_buff *skb,
525 struct sta_info *sta,
526 struct ieee80211_hdr *hdr)
527{
528 u32 msrmnt;
529 u16 tid;
530 u8 *qc;
531 int i, bin_range_count;
532 u32 *bin_ranges;
533 __le16 fc;
534 struct ieee80211_tx_latency_stat *tx_lat;
535 struct ieee80211_tx_latency_bin_ranges *tx_latency;
536 ktime_t skb_arv = skb->tstamp;
537
538 tx_latency = rcu_dereference(local->tx_latency);
539
540 /* assert Tx latency stats are enabled & frame arrived when enabled */
541 if (!tx_latency || !ktime_to_ns(skb_arv))
542 return;
543
544 fc = hdr->frame_control;
545
546 if (!ieee80211_is_data(fc)) /* make sure it is a data frame */
547 return;
548
549 /* get frame tid */
550 if (ieee80211_is_data_qos(hdr->frame_control)) {
551 qc = ieee80211_get_qos_ctl(hdr);
552 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
553 } else {
554 tid = 0;
555 }
556
557 tx_lat = &sta->tx_lat[tid];
558
559 /* Calculate the latency */
560 msrmnt = ktime_to_ms(ktime_sub(ktime_get(), skb_arv));
561
562 if (tx_lat->max < msrmnt) /* update stats */
563 tx_lat->max = msrmnt;
564 tx_lat->counter++;
565 tx_lat->sum += msrmnt;
566
567 if (!tx_lat->bins) /* bins not activated */
568 return;
569
570 /* count how many Tx frames transmitted with the appropriate latency */
571 bin_range_count = tx_latency->n_ranges;
572 bin_ranges = tx_latency->ranges;
573
574 for (i = 0; i < bin_range_count; i++) {
575 if (msrmnt <= bin_ranges[i]) {
576 tx_lat->bins[i]++;
577 break;
578 }
579 }
580 if (i == bin_range_count) /* msrmnt is bigger than the biggest range */
581 tx_lat->bins[i]++;
582}
583
584/*
585 * Use a static threshold for now, best value to be determined 517 * Use a static threshold for now, best value to be determined
586 * by testing ... 518 * by testing ...
587 * Should it depend on: 519 * Should it depend on:
@@ -853,12 +785,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
853 785
854 if (acked) 786 if (acked)
855 sta->last_ack_signal = info->status.ack_signal; 787 sta->last_ack_signal = info->status.ack_signal;
856
857 /*
858 * Measure frame removal for tx latency
859 * statistics calculation
860 */
861 ieee80211_tx_latency_end_msrmnt(local, skb, sta, hdr);
862 } 788 }
863 789
864 rcu_read_unlock(); 790 rcu_read_unlock();
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0e56ac5729ef..a23a84e93e80 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -20,7 +20,6 @@
20#include <linux/bitmap.h> 20#include <linux/bitmap.h>
21#include <linux/rcupdate.h> 21#include <linux/rcupdate.h>
22#include <linux/export.h> 22#include <linux/export.h>
23#include <linux/time.h>
24#include <net/net_namespace.h> 23#include <net/net_namespace.h>
25#include <net/ieee80211_radiotap.h> 24#include <net/ieee80211_radiotap.h>
26#include <net/cfg80211.h> 25#include <net/cfg80211.h>
@@ -1787,23 +1786,6 @@ fail:
1787 return NETDEV_TX_OK; /* meaning, we dealt with the skb */ 1786 return NETDEV_TX_OK; /* meaning, we dealt with the skb */
1788} 1787}
1789 1788
1790/*
1791 * Measure Tx frame arrival time for Tx latency statistics calculation
1792 * A single Tx frame latency should be measured from when it is entering the
1793 * Kernel until we receive Tx complete confirmation indication and the skb is
1794 * freed.
1795 */
1796static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local,
1797 struct sk_buff *skb)
1798{
1799 struct ieee80211_tx_latency_bin_ranges *tx_latency;
1800
1801 tx_latency = rcu_dereference(local->tx_latency);
1802 if (!tx_latency)
1803 return;
1804 skb->tstamp = ktime_get();
1805}
1806
1807/** 1789/**
1808 * ieee80211_build_hdr - build 802.11 header in the given frame 1790 * ieee80211_build_hdr - build 802.11 header in the given frame
1809 * @sdata: virtual interface to build the header for 1791 * @sdata: virtual interface to build the header for
@@ -2259,7 +2241,6 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2259 u32 info_flags) 2241 u32 info_flags)
2260{ 2242{
2261 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2243 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2262 struct ieee80211_local *local = sdata->local;
2263 2244
2264 if (unlikely(skb->len < ETH_HLEN)) { 2245 if (unlikely(skb->len < ETH_HLEN)) {
2265 kfree_skb(skb); 2246 kfree_skb(skb);
@@ -2268,9 +2249,6 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2268 2249
2269 rcu_read_lock(); 2250 rcu_read_lock();
2270 2251
2271 /* Measure frame arrival for Tx latency statistics calculation */
2272 ieee80211_tx_latency_start_msrmnt(local, skb);
2273
2274 skb = ieee80211_build_hdr(sdata, skb, info_flags); 2252 skb = ieee80211_build_hdr(sdata, skb, info_flags);
2275 if (IS_ERR(skb)) 2253 if (IS_ERR(skb))
2276 goto out; 2254 goto out;