Commit 0fdf1493 authored by Johannes Berg's avatar Johannes Berg

mac80211: allocate and fill tidstats only when needed

This fixes memory leaks in the case where we just have the
station info on the stack for internal usage without sending
it to cfg80211.

Fixes: 8689c051 ("cfg80211: dynamically allocate per-tid stats for station info")
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 39c1134c
......@@ -695,7 +695,7 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
if (sta) {
ret = 0;
memcpy(mac, sta->sta.addr, ETH_ALEN);
sta_set_sinfo(sta, sinfo);
sta_set_sinfo(sta, sinfo, true);
}
mutex_unlock(&local->sta_mtx);
......@@ -724,7 +724,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
sta = sta_info_get_bss(sdata, mac);
if (sta) {
ret = 0;
sta_set_sinfo(sta, sinfo);
sta_set_sinfo(sta, sinfo, true);
}
mutex_unlock(&local->sta_mtx);
......
......@@ -108,7 +108,7 @@ static void ieee80211_get_stats(struct net_device *dev,
goto do_survey;
memset(&sinfo, 0, sizeof(sinfo));
sta_set_sinfo(sta, &sinfo);
sta_set_sinfo(sta, &sinfo, false);
i = 0;
ADD_STA_STATS(sta);
......@@ -135,7 +135,7 @@ static void ieee80211_get_stats(struct net_device *dev,
continue;
memset(&sinfo, 0, sizeof(sinfo));
sta_set_sinfo(sta, &sinfo);
sta_set_sinfo(sta, &sinfo, false);
i = 0;
ADD_STA_STATS(sta);
}
......
......@@ -1008,7 +1008,7 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
if (sinfo)
sta_set_sinfo(sta, sinfo);
sta_set_sinfo(sta, sinfo, true);
cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL);
kfree(sinfo);
......@@ -2079,7 +2079,8 @@ static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats)
return value;
}
void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
bool tidstats)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
struct ieee80211_local *local = sdata->local;
......@@ -2233,7 +2234,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
}
if (!cfg80211_sinfo_alloc_tid_stats(sinfo, GFP_KERNEL)) {
if (tidstats && !cfg80211_sinfo_alloc_tid_stats(sinfo, GFP_KERNEL)) {
for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
struct cfg80211_tid_stats *tidstats = &sinfo->pertid[i];
......
......@@ -744,7 +744,8 @@ static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata)
void sta_set_rate_info_tx(struct sta_info *sta,
const struct ieee80211_tx_rate *rate,
struct rate_info *rinfo);
void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo);
void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
bool tidstats);
u32 sta_get_expected_throughput(struct sta_info *sta);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment