mac80211: add separate last_ack variable
authorJohannes Berg <johannes.berg@intel.com>
Thu, 31 Mar 2016 17:02:07 +0000 (20:02 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 Apr 2016 11:18:16 +0000 (13:18 +0200)
Instead of touching the rx_stats.last_rx from the status path, introduce
and use a status_stats.last_ack variable. This will make rx_stats.last_rx
indicate when the last frame was received, making it available for real
"last_rx" and statistics gathering; statistics, when done per-CPU, will
need to figure out which place was updated last for those items where the
"last" value is exposed.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/ibss.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/status.c

index b3407dbe4b7ddb462b0f0e013808cfe01d0d0e9c..c6d4b75eb60b34fed9585e9016dd0e97087bf856 100644 (file)
@@ -668,10 +668,11 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
        rcu_read_lock();
 
        list_for_each_entry_rcu(sta, &local->sta_list, list) {
+               unsigned long last_active = ieee80211_sta_last_active(sta);
+
                if (sta->sdata == sdata &&
-                   time_after(sta->rx_stats.last_rx +
-                              IEEE80211_IBSS_MERGE_INTERVAL,
-                              jiffies)) {
+                   time_is_after_jiffies(last_active +
+                                         IEEE80211_IBSS_MERGE_INTERVAL)) {
                        active++;
                        break;
                }
@@ -1255,11 +1256,13 @@ static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
        mutex_lock(&local->sta_mtx);
 
        list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
+               unsigned long last_active = ieee80211_sta_last_active(sta);
+
                if (sdata != sta->sdata)
                        continue;
 
-               if (time_after(jiffies, sta->rx_stats.last_rx + exp_time) ||
-                   (time_after(jiffies, sta->rx_stats.last_rx + exp_rsn) &&
+               if (time_is_before_jiffies(last_active + exp_time) ||
+                   (time_is_before_jiffies(last_active + exp_rsn) &&
                     sta->sta_state != IEEE80211_STA_AUTHORIZED)) {
                        sta_dbg(sta->sdata, "expiring inactive %sSTA %pM\n",
                                sta->sta_state != IEEE80211_STA_AUTHORIZED ?
index 4f19505f375704c248f71bc416e0ae3c852fb8d4..ac73b9c7e8d845204daadc8b4c2d8b3d134a9911 100644 (file)
@@ -1094,10 +1094,12 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
        mutex_lock(&local->sta_mtx);
 
        list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
+               unsigned long last_active = ieee80211_sta_last_active(sta);
+
                if (sdata != sta->sdata)
                        continue;
 
-               if (time_after(jiffies, sta->rx_stats.last_rx + exp_time)) {
+               if (time_is_before_jiffies(last_active + exp_time)) {
                        sta_dbg(sta->sdata, "expiring inactive STA %pM\n",
                                sta->sta.addr);
 
@@ -2000,7 +2002,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 
        sinfo->connected_time = ktime_get_seconds() - sta->last_connected;
        sinfo->inactive_time =
-               jiffies_to_msecs(jiffies - sta->rx_stats.last_rx);
+               jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta));
 
        if (!(sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES64) |
                               BIT(NL80211_STA_INFO_TX_BYTES)))) {
@@ -2186,3 +2188,10 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
                sinfo->expected_throughput = thr;
        }
 }
+
+unsigned long ieee80211_sta_last_active(struct sta_info *sta)
+{
+       if (time_after(sta->rx_stats.last_rx, sta->status_stats.last_ack))
+               return sta->rx_stats.last_rx;
+       return sta->status_stats.last_ack;
+}
index 93dc567e6100a318453c7b69afa2f05f9a1f5abf..8a8e84bfe3d2cfa67f62e80342de25ec438ca18d 100644 (file)
@@ -474,6 +474,7 @@ struct sta_info {
                unsigned long last_tdls_pkt_time;
                u64 msdu_retries[IEEE80211_NUM_TIDS + 1];
                u64 msdu_failed[IEEE80211_NUM_TIDS + 1];
+               unsigned long last_ack;
        } status_stats;
 
        /* Updated from TX path only, no locking requirements */
@@ -680,4 +681,6 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta);
 void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta);
 void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta);
 
+unsigned long ieee80211_sta_last_active(struct sta_info *sta);
+
 #endif /* STA_INFO_H */
index 8b1b2ea03eb5a13cc291c8d5e389b045e983ee47..c6d5c724e0326e04921969c9f00d11fac777749d 100644 (file)
@@ -188,7 +188,7 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
        struct ieee80211_sub_if_data *sdata = sta->sdata;
 
        if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
-               sta->rx_stats.last_rx = jiffies;
+               sta->status_stats.last_ack = jiffies;
 
        if (ieee80211_is_data_qos(mgmt->frame_control)) {
                struct ieee80211_hdr *hdr = (void *) skb->data;
@@ -647,7 +647,7 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
                sta->status_stats.retry_count += retry_count;
 
                if (acked) {
-                       sta->rx_stats.last_rx = jiffies;
+                       sta->status_stats.last_ack = jiffies;
 
                        if (sta->status_stats.lost_packets)
                                sta->status_stats.lost_packets = 0;