Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

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