Skip to content

Commit

Permalink
cfg80211/mac80211: revert to stack allocation for sinfo
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
jmberg-intel committed May 18, 2018
1 parent 8689c05 commit 73887fd
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 93 deletions.
32 changes: 13 additions & 19 deletions net/mac80211/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand All @@ -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; \
Expand All @@ -111,43 +107,41 @@ 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);

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) {
/* Make sure this station belongs to the proper 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;
Expand Down
86 changes: 27 additions & 59 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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++;
Expand All @@ -4773,7 +4769,6 @@ static int nl80211_dump_station(struct sk_buff *skb,
err = skb->len;
out_err:
rtnl_unlock();
kfree(sinfo);

return err;
}
Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
23 changes: 8 additions & 15 deletions net/wireless/wext-compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 */
Expand Down

0 comments on commit 73887fd

Please sign in to comment.