diff options
author | Johannes Berg <johannes.berg@intel.com> | 2016-03-31 19:02:08 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2016-04-06 13:18:17 +0200 |
commit | 4f6b1b3daaf167bf927174224e07efd17ed95984 (patch) | |
tree | 5591e35073577767d0ffb3eadaf74a3a2e0ce9ae /net/mac80211/rx.c | |
parent | mac80211: add separate last_ack variable (diff) | |
download | linux-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.c | 21 |
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) |