On Mon, Mar 04, 2013 at 06:02:58PM +0100, Johannes Berg wrote: > From: Johannes Berg <johannes.berg@xxxxxxxxx> > > 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@xxxxxxxxx> > --- > net/mac80211/cfg.c | 22 ++++++++++++++-------- > net/mac80211/sta_info.h | 9 +++++---- > net/mac80211/tx.c | 5 +++-- > 3 files changed, 22 insertions(+), 14 deletions(-) > > diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c > index 8259a5b..1ff629a 100644 > --- a/net/mac80211/cfg.c > +++ b/net/mac80211/cfg.c > @@ -445,12 +445,13 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) > struct ieee80211_sub_if_data *sdata = sta->sdata; > struct ieee80211_local *local = sdata->local; > struct timespec uptime; > + int ac; > > sinfo->generation = sdata->local->sta_generation; > > sinfo->filled = STATION_INFO_INACTIVE_TIME | > - STATION_INFO_RX_BYTES | > - STATION_INFO_TX_BYTES | > + STATION_INFO_RX_BYTES64 | > + STATION_INFO_TX_BYTES64 | > STATION_INFO_RX_PACKETS | > STATION_INFO_TX_PACKETS | > STATION_INFO_TX_RETRIES | > @@ -467,10 +468,14 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) > sinfo->connected_time = uptime.tv_sec - sta->last_connected; > > sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); > + sinfo->tx_bytes = 0; > + sinfo->tx_packets = 0; > + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { > + sinfo->tx_bytes += sta->tx_bytes[ac]; > + sinfo->tx_packets += sta->tx_packets[ac]; > + } > sinfo->rx_bytes = sta->rx_bytes; > - sinfo->tx_bytes = sta->tx_bytes; > sinfo->rx_packets = sta->rx_packets; > - sinfo->tx_packets = sta->tx_packets; > sinfo->tx_retries = sta->tx_retry_count; > sinfo->tx_failed = sta->tx_retry_failed; > sinfo->rx_dropped_misc = sta->rx_dropped; > @@ -598,8 +603,8 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, > data[i++] += sta->rx_fragments; \ > data[i++] += sta->rx_dropped; \ > \ > - data[i++] += sta->tx_packets; \ > - data[i++] += sta->tx_bytes; \ > + data[i++] += sinfo.tx_packets; \ > + data[i++] += sinfo.tx_bytes; \ > data[i++] += sta->tx_fragments; \ > data[i++] += sta->tx_filtered_count; \ > data[i++] += sta->tx_retry_failed; \ > @@ -621,13 +626,14 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, > if (!(sta && !WARN_ON(sta->sdata->dev != dev))) > goto do_survey; > > + sinfo.filled = 0; > + sta_set_sinfo(sta, &sinfo); > + > i = 0; > ADD_STA_STATS(sta); > > data[i++] = sta->sta_state; > > - sinfo.filled = 0; > - sta_set_sinfo(sta, &sinfo); > > if (sinfo.filled & STATION_INFO_TX_BITRATE) > data[i] = 100000 * > diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h > index e5868c3..0d4fec3 100644 > --- a/net/mac80211/sta_info.h > +++ b/net/mac80211/sta_info.h > @@ -333,7 +333,8 @@ struct sta_info { > unsigned long driver_buffered_tids; > > /* Updated from RX path only, no locking requirements */ > - unsigned long rx_packets, rx_bytes; > + unsigned long rx_packets; > + u64 rx_bytes; > unsigned long wep_weak_iv_count; > unsigned long last_rx; > long last_connected; > @@ -353,9 +354,9 @@ struct sta_info { > unsigned int fail_avg; > > /* Updated from TX path only, no locking requirements */ > - unsigned long tx_packets; > - unsigned long tx_bytes; > - unsigned long tx_fragments; > + u32 tx_packets[IEEE80211_NUM_ACS]; > + u32 tx_fragments; > + u64 tx_bytes[IEEE80211_NUM_ACS]; > struct ieee80211_tx_rate last_tx_rate; > int last_rx_rate_idx; > u32 last_rx_rate_flag; > diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c > index c79860f..6af7f60 100644 > --- a/net/mac80211/tx.c > +++ b/net/mac80211/tx.c > @@ -991,14 +991,15 @@ static ieee80211_tx_result debug_noinline > ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) > { > struct sk_buff *skb; > + int ac = skb_get_queue_mapping(tx->skb); > Here, ieee80211_tx_h_fragmentm has set tx->skb to NULL and this oopses. Karl -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html