aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2018-05-18 09:57:55 +0200
committerJohannes Berg <johannes.berg@intel.com>2018-05-18 11:14:35 +0200
commit73887fd906bb77a974fa02663df9937d0aff053a (patch)
tree9f2301560feb727cca41cb72fd8848dc302b7392
parentcfg80211: dynamically allocate per-tid stats for station info (diff)
downloadlinux-dev-73887fd906bb77a974fa02663df9937d0aff053a.tar.xz
linux-dev-73887fd906bb77a974fa02663df9937d0aff053a.zip
cfg80211/mac80211: revert to stack allocation for sinfo
Arend's previous patch made the sinfo structure smaller again by to dynamically allocating the per-tid stats only when needed. Thus, revert to stack allocation for the struct to simplify the code. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/ethtool.c32
-rw-r--r--net/wireless/nl80211.c86
-rw-r--r--net/wireless/wext-compat.c23
3 files changed, 48 insertions, 93 deletions
diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c
index 09210aa8ea9a..2ba5686cbcab 100644
--- a/net/mac80211/ethtool.c
+++ b/net/mac80211/ethtool.c
@@ -71,15 +71,11 @@ static void ieee80211_get_stats(struct net_device *dev,
struct ieee80211_channel *channel;
struct sta_info *sta;
struct ieee80211_local *local = sdata->local;
- struct station_info *sinfo;
+ struct station_info sinfo;
struct survey_info survey;
int i, q;
#define STA_STATS_SURVEY_LEN 7
- sinfo = kmalloc(sizeof(*sinfo), GFP_KERNEL);
- if (!sinfo)
- return;
-
memset(data, 0, sizeof(u64) * STA_STATS_LEN);
#define ADD_STA_STATS(sta) \
@@ -90,8 +86,8 @@ static void ieee80211_get_stats(struct net_device *dev,
data[i++] += sta->rx_stats.fragments; \
data[i++] += sta->rx_stats.dropped; \
\
- data[i++] += sinfo->tx_packets; \
- data[i++] += sinfo->tx_bytes; \
+ data[i++] += sinfo.tx_packets; \
+ data[i++] += sinfo.tx_bytes; \
data[i++] += sta->status_stats.filtered; \
data[i++] += sta->status_stats.retry_failed; \
data[i++] += sta->status_stats.retry_count; \
@@ -111,8 +107,8 @@ static void ieee80211_get_stats(struct net_device *dev,
if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
goto do_survey;
- memset(sinfo, 0, sizeof(*sinfo));
- sta_set_sinfo(sta, sinfo);
+ memset(&sinfo, 0, sizeof(sinfo));
+ sta_set_sinfo(sta, &sinfo);
i = 0;
ADD_STA_STATS(sta);
@@ -120,17 +116,17 @@ static void ieee80211_get_stats(struct net_device *dev,
data[i++] = sta->sta_state;
- if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE))
+ if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE))
data[i] = 100000ULL *
- cfg80211_calculate_bitrate(&sinfo->txrate);
+ cfg80211_calculate_bitrate(&sinfo.txrate);
i++;
- if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE))
+ if (sinfo.filled & BIT(NL80211_STA_INFO_RX_BITRATE))
data[i] = 100000ULL *
- cfg80211_calculate_bitrate(&sinfo->rxrate);
+ cfg80211_calculate_bitrate(&sinfo.rxrate);
i++;
- if (sinfo->filled & BIT(NL80211_STA_INFO_SIGNAL_AVG))
- data[i] = (u8)sinfo->signal_avg;
+ if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL_AVG))
+ data[i] = (u8)sinfo.signal_avg;
i++;
} else {
list_for_each_entry(sta, &local->sta_list, list) {
@@ -138,16 +134,14 @@ static void ieee80211_get_stats(struct net_device *dev,
if (sta->sdata->dev != dev)
continue;
- memset(sinfo, 0, sizeof(*sinfo));
- sta_set_sinfo(sta, sinfo);
+ memset(&sinfo, 0, sizeof(sinfo));
+ sta_set_sinfo(sta, &sinfo);
i = 0;
ADD_STA_STATS(sta);
}
}
do_survey:
- kfree(sinfo);
-
i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
/* Get survey stats for current channel */
survey.filled = 0;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 3d638f11edb5..7daceb1f253d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4723,17 +4723,13 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
static int nl80211_dump_station(struct sk_buff *skb,
struct netlink_callback *cb)
{
- struct station_info *sinfo;
+ struct station_info sinfo;
struct cfg80211_registered_device *rdev;
struct wireless_dev *wdev;
u8 mac_addr[ETH_ALEN];
int sta_idx = cb->args[2];
int err;
- sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
- if (!sinfo)
- return -ENOMEM;
-
rtnl_lock();
err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
if (err)
@@ -4750,9 +4746,9 @@ static int nl80211_dump_station(struct sk_buff *skb,
}
while (1) {
- memset(sinfo, 0, sizeof(*sinfo));
+ memset(&sinfo, 0, sizeof(sinfo));
err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
- mac_addr, sinfo);
+ mac_addr, &sinfo);
if (err == -ENOENT)
break;
if (err)
@@ -4762,7 +4758,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
rdev, wdev->netdev, mac_addr,
- sinfo) < 0)
+ &sinfo) < 0)
goto out;
sta_idx++;
@@ -4773,7 +4769,6 @@ static int nl80211_dump_station(struct sk_buff *skb,
err = skb->len;
out_err:
rtnl_unlock();
- kfree(sinfo);
return err;
}
@@ -4782,49 +4777,37 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1];
- struct station_info *sinfo;
+ struct station_info sinfo;
struct sk_buff *msg;
u8 *mac_addr = NULL;
int err;
- sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
- if (!sinfo)
- return -ENOMEM;
+ memset(&sinfo, 0, sizeof(sinfo));
- if (!info->attrs[NL80211_ATTR_MAC]) {
- err = -EINVAL;
- goto out;
- }
+ if (!info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
- if (!rdev->ops->get_station) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!rdev->ops->get_station)
+ return -EOPNOTSUPP;
- err = rdev_get_station(rdev, dev, mac_addr, sinfo);
+ err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
if (err)
- goto out;
+ return err;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg) {
- err = -ENOMEM;
- goto out;
- }
+ if (!msg)
+ return -ENOMEM;
if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
info->snd_portid, info->snd_seq, 0,
- rdev, dev, mac_addr, sinfo) < 0) {
+ rdev, dev, mac_addr, &sinfo) < 0) {
nlmsg_free(msg);
- err = -ENOBUFS;
- goto out;
+ return -ENOBUFS;
}
- err = genlmsg_reply(msg, info);
-out:
- kfree(sinfo);
- return err;
+ return genlmsg_reply(msg, info);
}
int cfg80211_check_station_change(struct wiphy *wiphy,
@@ -10088,26 +10071,18 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
*/
if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
rdev->ops->get_station) {
- struct station_info *sinfo;
+ struct station_info sinfo = {};
u8 *mac_addr;
- sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
- if (!sinfo)
- return -ENOMEM;
-
mac_addr = wdev->current_bss->pub.bssid;
- err = rdev_get_station(rdev, dev, mac_addr, sinfo);
- if (err) {
- kfree(sinfo);
+ err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
+ if (err)
return err;
- }
- if (sinfo->filled & BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
+ if (sinfo.filled & BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
wdev->cqm_config->last_rssi_event_value =
- (s8)sinfo->rx_beacon_signal_avg;
-
- kfree(sinfo);
+ (s8) sinfo.rx_beacon_signal_avg;
}
last = wdev->cqm_config->last_rssi_event_value;
@@ -14641,32 +14616,25 @@ void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct sk_buff *msg;
- struct station_info *empty_sinfo = NULL;
+ struct station_info empty_sinfo = {};
- if (!sinfo) {
- empty_sinfo = kzalloc(sizeof(*empty_sinfo), GFP_KERNEL);
- if (!empty_sinfo)
- return;
- sinfo = empty_sinfo;
- }
+ if (!sinfo)
+ sinfo = &empty_sinfo;
trace_cfg80211_del_sta(dev, mac_addr);
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
if (!msg)
- goto out;
+ return;
if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
rdev, dev, mac_addr, sinfo) < 0) {
nlmsg_free(msg);
- goto out;
+ return;
}
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
NL80211_MCGRP_MLME, gfp);
-
-out:
- kfree(empty_sinfo);
}
EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 9e002df0f8d8..05186a47878f 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1254,7 +1254,7 @@ static int cfg80211_wext_giwrate(struct net_device *dev,
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
- struct station_info *sinfo;
+ struct station_info sinfo = {};
u8 addr[ETH_ALEN];
int err;
@@ -1274,23 +1274,16 @@ static int cfg80211_wext_giwrate(struct net_device *dev,
if (err)
return err;
- sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
- if (!sinfo)
- return -ENOMEM;
-
- err = rdev_get_station(rdev, dev, addr, sinfo);
+ err = rdev_get_station(rdev, dev, addr, &sinfo);
if (err)
- goto out;
+ return err;
- if (!(sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE))) {
- err = -EOPNOTSUPP;
- goto out;
- }
+ if (!(sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)))
+ return -EOPNOTSUPP;
- rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo->txrate);
-out:
- kfree(sinfo);
- return err;
+ rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
+
+ return 0;
}
/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */