summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2018-05-18 03:57:55 -0400
committerJohannes Berg <johannes.berg@intel.com>2018-05-18 05:14:35 -0400
commit73887fd906bb77a974fa02663df9937d0aff053a (patch)
tree9f2301560feb727cca41cb72fd8848dc302b7392
parent8689c051a20195b228e19acb155c7d6e48a86753 (diff)
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,
71 struct ieee80211_channel *channel; 71 struct ieee80211_channel *channel;
72 struct sta_info *sta; 72 struct sta_info *sta;
73 struct ieee80211_local *local = sdata->local; 73 struct ieee80211_local *local = sdata->local;
74 struct station_info *sinfo; 74 struct station_info sinfo;
75 struct survey_info survey; 75 struct survey_info survey;
76 int i, q; 76 int i, q;
77#define STA_STATS_SURVEY_LEN 7 77#define STA_STATS_SURVEY_LEN 7
78 78
79 sinfo = kmalloc(sizeof(*sinfo), GFP_KERNEL);
80 if (!sinfo)
81 return;
82
83 memset(data, 0, sizeof(u64) * STA_STATS_LEN); 79 memset(data, 0, sizeof(u64) * STA_STATS_LEN);
84 80
85#define ADD_STA_STATS(sta) \ 81#define ADD_STA_STATS(sta) \
@@ -90,8 +86,8 @@ static void ieee80211_get_stats(struct net_device *dev,
90 data[i++] += sta->rx_stats.fragments; \ 86 data[i++] += sta->rx_stats.fragments; \
91 data[i++] += sta->rx_stats.dropped; \ 87 data[i++] += sta->rx_stats.dropped; \
92 \ 88 \
93 data[i++] += sinfo->tx_packets; \ 89 data[i++] += sinfo.tx_packets; \
94 data[i++] += sinfo->tx_bytes; \ 90 data[i++] += sinfo.tx_bytes; \
95 data[i++] += sta->status_stats.filtered; \ 91 data[i++] += sta->status_stats.filtered; \
96 data[i++] += sta->status_stats.retry_failed; \ 92 data[i++] += sta->status_stats.retry_failed; \
97 data[i++] += sta->status_stats.retry_count; \ 93 data[i++] += sta->status_stats.retry_count; \
@@ -111,8 +107,8 @@ static void ieee80211_get_stats(struct net_device *dev,
111 if (!(sta && !WARN_ON(sta->sdata->dev != dev))) 107 if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
112 goto do_survey; 108 goto do_survey;
113 109
114 memset(sinfo, 0, sizeof(*sinfo)); 110 memset(&sinfo, 0, sizeof(sinfo));
115 sta_set_sinfo(sta, sinfo); 111 sta_set_sinfo(sta, &sinfo);
116 112
117 i = 0; 113 i = 0;
118 ADD_STA_STATS(sta); 114 ADD_STA_STATS(sta);
@@ -120,17 +116,17 @@ static void ieee80211_get_stats(struct net_device *dev,
120 data[i++] = sta->sta_state; 116 data[i++] = sta->sta_state;
121 117
122 118
123 if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE)) 119 if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE))
124 data[i] = 100000ULL * 120 data[i] = 100000ULL *
125 cfg80211_calculate_bitrate(&sinfo->txrate); 121 cfg80211_calculate_bitrate(&sinfo.txrate);
126 i++; 122 i++;
127 if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE)) 123 if (sinfo.filled & BIT(NL80211_STA_INFO_RX_BITRATE))
128 data[i] = 100000ULL * 124 data[i] = 100000ULL *
129 cfg80211_calculate_bitrate(&sinfo->rxrate); 125 cfg80211_calculate_bitrate(&sinfo.rxrate);
130 i++; 126 i++;
131 127
132 if (sinfo->filled & BIT(NL80211_STA_INFO_SIGNAL_AVG)) 128 if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL_AVG))
133 data[i] = (u8)sinfo->signal_avg; 129 data[i] = (u8)sinfo.signal_avg;
134 i++; 130 i++;
135 } else { 131 } else {
136 list_for_each_entry(sta, &local->sta_list, list) { 132 list_for_each_entry(sta, &local->sta_list, list) {
@@ -138,16 +134,14 @@ static void ieee80211_get_stats(struct net_device *dev,
138 if (sta->sdata->dev != dev) 134 if (sta->sdata->dev != dev)
139 continue; 135 continue;
140 136
141 memset(sinfo, 0, sizeof(*sinfo)); 137 memset(&sinfo, 0, sizeof(sinfo));
142 sta_set_sinfo(sta, sinfo); 138 sta_set_sinfo(sta, &sinfo);
143 i = 0; 139 i = 0;
144 ADD_STA_STATS(sta); 140 ADD_STA_STATS(sta);
145 } 141 }
146 } 142 }
147 143
148do_survey: 144do_survey:
149 kfree(sinfo);
150
151 i = STA_STATS_LEN - STA_STATS_SURVEY_LEN; 145 i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
152 /* Get survey stats for current channel */ 146 /* Get survey stats for current channel */
153 survey.filled = 0; 147 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,
4723static int nl80211_dump_station(struct sk_buff *skb, 4723static int nl80211_dump_station(struct sk_buff *skb,
4724 struct netlink_callback *cb) 4724 struct netlink_callback *cb)
4725{ 4725{
4726 struct station_info *sinfo; 4726 struct station_info sinfo;
4727 struct cfg80211_registered_device *rdev; 4727 struct cfg80211_registered_device *rdev;
4728 struct wireless_dev *wdev; 4728 struct wireless_dev *wdev;
4729 u8 mac_addr[ETH_ALEN]; 4729 u8 mac_addr[ETH_ALEN];
4730 int sta_idx = cb->args[2]; 4730 int sta_idx = cb->args[2];
4731 int err; 4731 int err;
4732 4732
4733 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
4734 if (!sinfo)
4735 return -ENOMEM;
4736
4737 rtnl_lock(); 4733 rtnl_lock();
4738 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); 4734 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
4739 if (err) 4735 if (err)
@@ -4750,9 +4746,9 @@ static int nl80211_dump_station(struct sk_buff *skb,
4750 } 4746 }
4751 4747
4752 while (1) { 4748 while (1) {
4753 memset(sinfo, 0, sizeof(*sinfo)); 4749 memset(&sinfo, 0, sizeof(sinfo));
4754 err = rdev_dump_station(rdev, wdev->netdev, sta_idx, 4750 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
4755 mac_addr, sinfo); 4751 mac_addr, &sinfo);
4756 if (err == -ENOENT) 4752 if (err == -ENOENT)
4757 break; 4753 break;
4758 if (err) 4754 if (err)
@@ -4762,7 +4758,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
4762 NETLINK_CB(cb->skb).portid, 4758 NETLINK_CB(cb->skb).portid,
4763 cb->nlh->nlmsg_seq, NLM_F_MULTI, 4759 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4764 rdev, wdev->netdev, mac_addr, 4760 rdev, wdev->netdev, mac_addr,
4765 sinfo) < 0) 4761 &sinfo) < 0)
4766 goto out; 4762 goto out;
4767 4763
4768 sta_idx++; 4764 sta_idx++;
@@ -4773,7 +4769,6 @@ static int nl80211_dump_station(struct sk_buff *skb,
4773 err = skb->len; 4769 err = skb->len;
4774 out_err: 4770 out_err:
4775 rtnl_unlock(); 4771 rtnl_unlock();
4776 kfree(sinfo);
4777 4772
4778 return err; 4773 return err;
4779} 4774}
@@ -4782,49 +4777,37 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
4782{ 4777{
4783 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4778 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4784 struct net_device *dev = info->user_ptr[1]; 4779 struct net_device *dev = info->user_ptr[1];
4785 struct station_info *sinfo; 4780 struct station_info sinfo;
4786 struct sk_buff *msg; 4781 struct sk_buff *msg;
4787 u8 *mac_addr = NULL; 4782 u8 *mac_addr = NULL;
4788 int err; 4783 int err;
4789 4784
4790 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); 4785 memset(&sinfo, 0, sizeof(sinfo));
4791 if (!sinfo)
4792 return -ENOMEM;
4793 4786
4794 if (!info->attrs[NL80211_ATTR_MAC]) { 4787 if (!info->attrs[NL80211_ATTR_MAC])
4795 err = -EINVAL; 4788 return -EINVAL;
4796 goto out;
4797 }
4798 4789
4799 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 4790 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4800 4791
4801 if (!rdev->ops->get_station) { 4792 if (!rdev->ops->get_station)
4802 err = -EOPNOTSUPP; 4793 return -EOPNOTSUPP;
4803 goto out;
4804 }
4805 4794
4806 err = rdev_get_station(rdev, dev, mac_addr, sinfo); 4795 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
4807 if (err) 4796 if (err)
4808 goto out; 4797 return err;
4809 4798
4810 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4799 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4811 if (!msg) { 4800 if (!msg)
4812 err = -ENOMEM; 4801 return -ENOMEM;
4813 goto out;
4814 }
4815 4802
4816 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 4803 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
4817 info->snd_portid, info->snd_seq, 0, 4804 info->snd_portid, info->snd_seq, 0,
4818 rdev, dev, mac_addr, sinfo) < 0) { 4805 rdev, dev, mac_addr, &sinfo) < 0) {
4819 nlmsg_free(msg); 4806 nlmsg_free(msg);
4820 err = -ENOBUFS; 4807 return -ENOBUFS;
4821 goto out;
4822 } 4808 }
4823 4809
4824 err = genlmsg_reply(msg, info); 4810 return genlmsg_reply(msg, info);
4825out:
4826 kfree(sinfo);
4827 return err;
4828} 4811}
4829 4812
4830int cfg80211_check_station_change(struct wiphy *wiphy, 4813int cfg80211_check_station_change(struct wiphy *wiphy,
@@ -10088,26 +10071,18 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
10088 */ 10071 */
10089 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss && 10072 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
10090 rdev->ops->get_station) { 10073 rdev->ops->get_station) {
10091 struct station_info *sinfo; 10074 struct station_info sinfo = {};
10092 u8 *mac_addr; 10075 u8 *mac_addr;
10093 10076
10094 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
10095 if (!sinfo)
10096 return -ENOMEM;
10097
10098 mac_addr = wdev->current_bss->pub.bssid; 10077 mac_addr = wdev->current_bss->pub.bssid;
10099 10078
10100 err = rdev_get_station(rdev, dev, mac_addr, sinfo); 10079 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
10101 if (err) { 10080 if (err)
10102 kfree(sinfo);
10103 return err; 10081 return err;
10104 }
10105 10082
10106 if (sinfo->filled & BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG)) 10083 if (sinfo.filled & BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
10107 wdev->cqm_config->last_rssi_event_value = 10084 wdev->cqm_config->last_rssi_event_value =
10108 (s8)sinfo->rx_beacon_signal_avg; 10085 (s8) sinfo.rx_beacon_signal_avg;
10109
10110 kfree(sinfo);
10111 } 10086 }
10112 10087
10113 last = wdev->cqm_config->last_rssi_event_value; 10088 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,
14641 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 14616 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
14642 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); 14617 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14643 struct sk_buff *msg; 14618 struct sk_buff *msg;
14644 struct station_info *empty_sinfo = NULL; 14619 struct station_info empty_sinfo = {};
14645 14620
14646 if (!sinfo) { 14621 if (!sinfo)
14647 empty_sinfo = kzalloc(sizeof(*empty_sinfo), GFP_KERNEL); 14622 sinfo = &empty_sinfo;
14648 if (!empty_sinfo)
14649 return;
14650 sinfo = empty_sinfo;
14651 }
14652 14623
14653 trace_cfg80211_del_sta(dev, mac_addr); 14624 trace_cfg80211_del_sta(dev, mac_addr);
14654 14625
14655 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 14626 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14656 if (!msg) 14627 if (!msg)
14657 goto out; 14628 return;
14658 14629
14659 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0, 14630 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
14660 rdev, dev, mac_addr, sinfo) < 0) { 14631 rdev, dev, mac_addr, sinfo) < 0) {
14661 nlmsg_free(msg); 14632 nlmsg_free(msg);
14662 goto out; 14633 return;
14663 } 14634 }
14664 14635
14665 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, 14636 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
14666 NL80211_MCGRP_MLME, gfp); 14637 NL80211_MCGRP_MLME, gfp);
14667
14668out:
14669 kfree(empty_sinfo);
14670} 14638}
14671EXPORT_SYMBOL(cfg80211_del_sta_sinfo); 14639EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
14672 14640
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,
1254{ 1254{
1255 struct wireless_dev *wdev = dev->ieee80211_ptr; 1255 struct wireless_dev *wdev = dev->ieee80211_ptr;
1256 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 1256 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1257 struct station_info *sinfo; 1257 struct station_info sinfo = {};
1258 u8 addr[ETH_ALEN]; 1258 u8 addr[ETH_ALEN];
1259 int err; 1259 int err;
1260 1260
@@ -1274,23 +1274,16 @@ static int cfg80211_wext_giwrate(struct net_device *dev,
1274 if (err) 1274 if (err)
1275 return err; 1275 return err;
1276 1276
1277 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); 1277 err = rdev_get_station(rdev, dev, addr, &sinfo);
1278 if (!sinfo)
1279 return -ENOMEM;
1280
1281 err = rdev_get_station(rdev, dev, addr, sinfo);
1282 if (err) 1278 if (err)
1283 goto out; 1279 return err;
1284 1280
1285 if (!(sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE))) { 1281 if (!(sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)))
1286 err = -EOPNOTSUPP; 1282 return -EOPNOTSUPP;
1287 goto out;
1288 }
1289 1283
1290 rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo->txrate); 1284 rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
1291out: 1285
1292 kfree(sinfo); 1286 return 0;
1293 return err;
1294} 1287}
1295 1288
1296/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ 1289/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */