summaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2016-03-31 19:02:08 +0200
committerJohannes Berg <johannes.berg@intel.com>2016-04-06 13:18:17 +0200
commit4f6b1b3daaf167bf927174224e07efd17ed95984 (patch)
tree5591e35073577767d0ffb3eadaf74a3a2e0ce9ae /net/mac80211/rx.c
parentmac80211: add separate last_ack variable (diff)
downloadlinux-4f6b1b3daaf167bf927174224e07efd17ed95984.tar.xz
linux-4f6b1b3daaf167bf927174224e07efd17ed95984.zip
mac80211: fix last RX rate data consistency
When storing the last_rate_* values in the RX code, there's nothing to guarantee consistency, so a concurrent reader could see, e.g. last_rate_idx on the new value, but last_rate_flag still on the old, getting completely bogus values in the end. To fix this, I lifted the sta_stats_encode_rate() function from my old rate statistics code, which encodes the entire rate data into a single 16-bit value, avoiding the consistency issue. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c21
1 files changed, 5 insertions, 16 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d14c66df9e86..5a6c36c3aed6 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1421,16 +1421,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
sta->rx_stats.last_rx = jiffies;
if (ieee80211_is_data(hdr->frame_control) &&
- !is_multicast_ether_addr(hdr->addr1)) {
- sta->rx_stats.last_rate_idx =
- status->rate_idx;
- sta->rx_stats.last_rate_flag =
- status->flag;
- sta->rx_stats.last_rate_vht_flag =
- status->vht_flag;
- sta->rx_stats.last_rate_vht_nss =
- status->vht_nss;
- }
+ !is_multicast_ether_addr(hdr->addr1))
+ sta->rx_stats.last_rate =
+ sta_stats_encode_rate(status);
}
} else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) {
sta->rx_stats.last_rx = jiffies;
@@ -1440,12 +1433,8 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
* match the current local configuration when processed.
*/
sta->rx_stats.last_rx = jiffies;
- if (ieee80211_is_data(hdr->frame_control)) {
- sta->rx_stats.last_rate_idx = status->rate_idx;
- sta->rx_stats.last_rate_flag = status->flag;
- sta->rx_stats.last_rate_vht_flag = status->vht_flag;
- sta->rx_stats.last_rate_vht_nss = status->vht_nss;
- }
+ if (ieee80211_is_data(hdr->frame_control))
+ sta->rx_stats.last_rate = sta_stats_encode_rate(status);
}
if (rx->sdata->vif.type == NL80211_IFTYPE_STATION)