Commit 560d268220d3416a2d473bcc906ea2ccbf51e4ec

Authored by Johannes Berg
1 parent 87f59c70ce

mac80211: provide race-free 64-bit traffic counters

Make the TX bytes/packets counters race-free by keeping
them per AC so concurrent TX on queues can't cause lost
or wrong updates. This works since each station belongs
to a single interface. While at it also make the bytes
counters 64-bit.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>

Showing 3 changed files with 25 additions and 14 deletions Side-by-side Diff

... ... @@ -445,12 +445,14 @@
445 445 struct ieee80211_sub_if_data *sdata = sta->sdata;
446 446 struct ieee80211_local *local = sdata->local;
447 447 struct timespec uptime;
  448 + u64 packets = 0;
  449 + int ac;
448 450  
449 451 sinfo->generation = sdata->local->sta_generation;
450 452  
451 453 sinfo->filled = STATION_INFO_INACTIVE_TIME |
452   - STATION_INFO_RX_BYTES |
453   - STATION_INFO_TX_BYTES |
  454 + STATION_INFO_RX_BYTES64 |
  455 + STATION_INFO_TX_BYTES64 |
454 456 STATION_INFO_RX_PACKETS |
455 457 STATION_INFO_TX_PACKETS |
456 458 STATION_INFO_TX_RETRIES |
457 459  
458 460  
... ... @@ -467,10 +469,14 @@
467 469 sinfo->connected_time = uptime.tv_sec - sta->last_connected;
468 470  
469 471 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
  472 + sinfo->tx_bytes = 0;
  473 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
  474 + sinfo->tx_bytes += sta->tx_bytes[ac];
  475 + packets += sta->tx_packets[ac];
  476 + }
  477 + sinfo->tx_packets = packets;
470 478 sinfo->rx_bytes = sta->rx_bytes;
471   - sinfo->tx_bytes = sta->tx_bytes;
472 479 sinfo->rx_packets = sta->rx_packets;
473   - sinfo->tx_packets = sta->tx_packets;
474 480 sinfo->tx_retries = sta->tx_retry_count;
475 481 sinfo->tx_failed = sta->tx_retry_failed;
476 482 sinfo->rx_dropped_misc = sta->rx_dropped;
... ... @@ -598,8 +604,8 @@
598 604 data[i++] += sta->rx_fragments; \
599 605 data[i++] += sta->rx_dropped; \
600 606 \
601   - data[i++] += sta->tx_packets; \
602   - data[i++] += sta->tx_bytes; \
  607 + data[i++] += sinfo.tx_packets; \
  608 + data[i++] += sinfo.tx_bytes; \
603 609 data[i++] += sta->tx_fragments; \
604 610 data[i++] += sta->tx_filtered_count; \
605 611 data[i++] += sta->tx_retry_failed; \
606 612  
... ... @@ -621,13 +627,14 @@
621 627 if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
622 628 goto do_survey;
623 629  
  630 + sinfo.filled = 0;
  631 + sta_set_sinfo(sta, &sinfo);
  632 +
624 633 i = 0;
625 634 ADD_STA_STATS(sta);
626 635  
627 636 data[i++] = sta->sta_state;
628 637  
629   - sinfo.filled = 0;
630   - sta_set_sinfo(sta, &sinfo);
631 638  
632 639 if (sinfo.filled & STATION_INFO_TX_BITRATE)
633 640 data[i] = 100000 *
net/mac80211/sta_info.h
... ... @@ -333,7 +333,8 @@
333 333 unsigned long driver_buffered_tids;
334 334  
335 335 /* Updated from RX path only, no locking requirements */
336   - unsigned long rx_packets, rx_bytes;
  336 + unsigned long rx_packets;
  337 + u64 rx_bytes;
337 338 unsigned long wep_weak_iv_count;
338 339 unsigned long last_rx;
339 340 long last_connected;
... ... @@ -353,9 +354,9 @@
353 354 unsigned int fail_avg;
354 355  
355 356 /* Updated from TX path only, no locking requirements */
356   - unsigned long tx_packets;
357   - unsigned long tx_bytes;
358   - unsigned long tx_fragments;
  357 + u32 tx_fragments;
  358 + u64 tx_packets[IEEE80211_NUM_ACS];
  359 + u64 tx_bytes[IEEE80211_NUM_ACS];
359 360 struct ieee80211_tx_rate last_tx_rate;
360 361 int last_rx_rate_idx;
361 362 u32 last_rx_rate_flag;
... ... @@ -991,15 +991,18 @@
991 991 ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
992 992 {
993 993 struct sk_buff *skb;
  994 + int ac = -1;
994 995  
995 996 if (!tx->sta)
996 997 return TX_CONTINUE;
997 998  
998   - tx->sta->tx_packets++;
999 999 skb_queue_walk(&tx->skbs, skb) {
  1000 + ac = skb_get_queue_mapping(skb);
1000 1001 tx->sta->tx_fragments++;
1001   - tx->sta->tx_bytes += skb->len;
  1002 + tx->sta->tx_bytes[ac] += skb->len;
1002 1003 }
  1004 + if (ac >= 0)
  1005 + tx->sta->tx_packets[ac]++;
1003 1006  
1004 1007 return TX_CONTINUE;
1005 1008 }