mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
wifi: mac80211: add support to accumulate removed link statistics
Currently, if a link gets removed in between for a station then directly accumulated data will fall down to sum of other active links. This will bring inconsistency in station dump statistics. For instance, let's take Tx packets - at t=0-> link-0:2 link-1:3 Tx packets => accumulated = 5 - at t=1-> link-0:4 link-1:6 Tx packets => accumulated = 10 let say at t=2, link-0 went down => link-0:0 link-1:7 => accumulated = 7 Here, suddenly accumulated Tx packets will come down to 7 from 10. This is showing inconsistency. Therefore, store link-0 data when it went down and add to accumulated Tx packet = 11. Hence, store the removed link statistics data in sta structure and add it in accumulated statistics for consistency. Signed-off-by: Sarika Sharma <quic_sarishar@quicinc.com> Link: https://patch.msgid.link/20250528054420.3050133-7-quic_sarishar@quicinc.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
49e47223ec
commit
80b2fa4679
@ -886,6 +886,13 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
ret = 0;
|
||||
memcpy(mac, sta->sta.addr, ETH_ALEN);
|
||||
sta_set_sinfo(sta, sinfo, true);
|
||||
|
||||
/* Add accumulated removed link data to sinfo data for
|
||||
* consistency for MLO
|
||||
*/
|
||||
if (sinfo->valid_links)
|
||||
sta_set_accumulated_removed_links_sinfo(sta, sinfo);
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -913,6 +920,12 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
if (sta) {
|
||||
ret = 0;
|
||||
sta_set_sinfo(sta, sinfo, true);
|
||||
|
||||
/* Add accumulated removed link data to sinfo data for
|
||||
* consistency for MLO
|
||||
*/
|
||||
if (sinfo->valid_links)
|
||||
sta_set_accumulated_removed_links_sinfo(sta, sinfo);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@ -355,6 +355,50 @@ static void sta_info_free_link(struct link_sta_info *link_sta)
|
||||
free_percpu(link_sta->pcpu_rx_stats);
|
||||
}
|
||||
|
||||
static void sta_accumulate_removed_link_stats(struct sta_info *sta, int link_id)
|
||||
{
|
||||
struct link_sta_info *link_sta = wiphy_dereference(sta->local->hw.wiphy,
|
||||
sta->link[link_id]);
|
||||
struct ieee80211_link_data *link;
|
||||
int ac, tid;
|
||||
u32 thr;
|
||||
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
||||
sta->rem_link_stats.tx_packets +=
|
||||
link_sta->tx_stats.packets[ac];
|
||||
sta->rem_link_stats.tx_bytes += link_sta->tx_stats.bytes[ac];
|
||||
}
|
||||
|
||||
sta->rem_link_stats.rx_packets += link_sta->rx_stats.packets;
|
||||
sta->rem_link_stats.rx_bytes += link_sta->rx_stats.bytes;
|
||||
sta->rem_link_stats.tx_retries += link_sta->status_stats.retry_count;
|
||||
sta->rem_link_stats.tx_failed += link_sta->status_stats.retry_failed;
|
||||
sta->rem_link_stats.rx_dropped_misc += link_sta->rx_stats.dropped;
|
||||
|
||||
thr = sta_get_expected_throughput(sta);
|
||||
if (thr != 0)
|
||||
sta->rem_link_stats.expected_throughput += thr;
|
||||
|
||||
for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) {
|
||||
sta->rem_link_stats.pertid_stats.rx_msdu +=
|
||||
link_sta->rx_stats.msdu[tid];
|
||||
sta->rem_link_stats.pertid_stats.tx_msdu +=
|
||||
link_sta->tx_stats.msdu[tid];
|
||||
sta->rem_link_stats.pertid_stats.tx_msdu_retries +=
|
||||
link_sta->status_stats.msdu_retries[tid];
|
||||
sta->rem_link_stats.pertid_stats.tx_msdu_failed +=
|
||||
link_sta->status_stats.msdu_failed[tid];
|
||||
}
|
||||
|
||||
if (sta->sdata->vif.type == NL80211_IFTYPE_STATION) {
|
||||
link = wiphy_dereference(sta->sdata->local->hw.wiphy,
|
||||
sta->sdata->link[link_id]);
|
||||
if (link)
|
||||
sta->rem_link_stats.beacon_loss_count +=
|
||||
link->u.mgd.beacon_loss_count;
|
||||
}
|
||||
}
|
||||
|
||||
static void sta_remove_link(struct sta_info *sta, unsigned int link_id,
|
||||
bool unhash)
|
||||
{
|
||||
@ -377,6 +421,10 @@ static void sta_remove_link(struct sta_info *sta, unsigned int link_id,
|
||||
alloc = container_of(link_sta, typeof(*alloc), info);
|
||||
|
||||
sta->sta.valid_links &= ~BIT(link_id);
|
||||
|
||||
/* store removed link info for accumulated stats consistency */
|
||||
sta_accumulate_removed_link_stats(sta, link_id);
|
||||
|
||||
RCU_INIT_POINTER(sta->link[link_id], NULL);
|
||||
RCU_INIT_POINTER(sta->sta.link[link_id], NULL);
|
||||
if (alloc) {
|
||||
@ -2645,6 +2693,32 @@ static void sta_set_mesh_sinfo(struct sta_info *sta,
|
||||
}
|
||||
#endif
|
||||
|
||||
void sta_set_accumulated_removed_links_sinfo(struct sta_info *sta,
|
||||
struct station_info *sinfo)
|
||||
{
|
||||
/* Accumulating the removed link statistics. */
|
||||
sinfo->tx_packets = sta->rem_link_stats.tx_packets;
|
||||
sinfo->rx_packets = sta->rem_link_stats.rx_packets;
|
||||
sinfo->tx_bytes = sta->rem_link_stats.tx_bytes;
|
||||
sinfo->rx_bytes = sta->rem_link_stats.rx_bytes;
|
||||
sinfo->tx_retries = sta->rem_link_stats.tx_retries;
|
||||
sinfo->tx_failed = sta->rem_link_stats.tx_failed;
|
||||
sinfo->rx_dropped_misc = sta->rem_link_stats.rx_dropped_misc;
|
||||
sinfo->beacon_loss_count = sta->rem_link_stats.beacon_loss_count;
|
||||
sinfo->expected_throughput = sta->rem_link_stats.expected_throughput;
|
||||
|
||||
if (sinfo->pertid) {
|
||||
sinfo->pertid->rx_msdu =
|
||||
sta->rem_link_stats.pertid_stats.rx_msdu;
|
||||
sinfo->pertid->tx_msdu =
|
||||
sta->rem_link_stats.pertid_stats.tx_msdu;
|
||||
sinfo->pertid->tx_msdu_retries =
|
||||
sta->rem_link_stats.pertid_stats.tx_msdu_retries;
|
||||
sinfo->pertid->tx_msdu_failed =
|
||||
sta->rem_link_stats.pertid_stats.tx_msdu_failed;
|
||||
}
|
||||
}
|
||||
|
||||
void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
|
||||
bool tidstats)
|
||||
{
|
||||
|
||||
@ -568,6 +568,58 @@ struct link_sta_info {
|
||||
struct ieee80211_link_sta *pub;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_sta_removed_link_stats - Removed link sta data
|
||||
*
|
||||
* keep required accumulated removed link data for stats
|
||||
*
|
||||
* @rx_packets: accumulated packets (MSDUs & MMPDUs) received from
|
||||
* this station for removed links
|
||||
* @tx_packets: accumulated packets (MSDUs & MMPDUs) transmitted to
|
||||
* this station for removed links
|
||||
* @rx_bytes: accumulated bytes (size of MPDUs) received from this
|
||||
* station for removed links
|
||||
* @tx_bytes: accumulated bytes (size of MPDUs) transmitted to this
|
||||
* station for removed links
|
||||
* @tx_retries: cumulative retry counts (MPDUs) for removed links
|
||||
* @tx_failed: accumulated number of failed transmissions (MPDUs)
|
||||
* (retries exceeded, no ACK) for removed links
|
||||
* @rx_dropped_misc: accumulated dropped packets for un-specified reason
|
||||
* from this station for removed links
|
||||
* @beacon_loss_count: Number of times beacon loss event has triggered
|
||||
* from this station for removed links.
|
||||
* @expected_throughput: expected throughput in kbps (including 802.11
|
||||
* headers) towards this station for removed links
|
||||
* @pertid_stats: accumulated per-TID statistics for removed link of
|
||||
* station
|
||||
* @pertid_stats.rx_msdu : accumulated number of received MSDUs towards
|
||||
* this station for removed links.
|
||||
* @pertid_stats.tx_msdu: accumulated number of (attempted) transmitted
|
||||
* MSDUs towards this station for removed links
|
||||
* @pertid_stats.tx_msdu_retries: accumulated number of retries (not
|
||||
* counting the first) for transmitted MSDUs towards this station
|
||||
* for removed links
|
||||
* @pertid_stats.tx_msdu_failed: accumulated number of failed transmitted
|
||||
* MSDUs towards this station for removed links
|
||||
*/
|
||||
struct ieee80211_sta_removed_link_stats {
|
||||
u32 rx_packets;
|
||||
u32 tx_packets;
|
||||
u64 rx_bytes;
|
||||
u64 tx_bytes;
|
||||
u32 tx_retries;
|
||||
u32 tx_failed;
|
||||
u32 rx_dropped_misc;
|
||||
u32 beacon_loss_count;
|
||||
u32 expected_throughput;
|
||||
struct {
|
||||
u64 rx_msdu;
|
||||
u64 tx_msdu;
|
||||
u64 tx_msdu_retries;
|
||||
u64 tx_msdu_failed;
|
||||
} pertid_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sta_info - STA information
|
||||
*
|
||||
@ -644,6 +696,7 @@ struct link_sta_info {
|
||||
* @deflink address and remaining would be allocated and the address
|
||||
* would be assigned to link[link_id] where link_id is the id assigned
|
||||
* by the AP.
|
||||
* @rem_link_stats: accumulated removed link stats
|
||||
*/
|
||||
struct sta_info {
|
||||
/* General information, mostly static */
|
||||
@ -718,6 +771,7 @@ struct sta_info {
|
||||
struct ieee80211_sta_aggregates cur;
|
||||
struct link_sta_info deflink;
|
||||
struct link_sta_info __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||
struct ieee80211_sta_removed_link_stats rem_link_stats;
|
||||
|
||||
/* keep last! */
|
||||
struct ieee80211_sta sta;
|
||||
@ -922,6 +976,9 @@ void sta_set_rate_info_tx(struct sta_info *sta,
|
||||
void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
|
||||
bool tidstats);
|
||||
|
||||
void sta_set_accumulated_removed_links_sinfo(struct sta_info *sta,
|
||||
struct station_info *sinfo);
|
||||
|
||||
u32 sta_get_expected_throughput(struct sta_info *sta);
|
||||
|
||||
void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user