From patchwork Wed May 9 12:13:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 10389335 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D357960153 for ; Wed, 9 May 2018 12:13:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C333E28F46 for ; Wed, 9 May 2018 12:13:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B7D0E28F4A; Wed, 9 May 2018 12:13:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 45BFF28F46 for ; Wed, 9 May 2018 12:13:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934728AbeEIMNv (ORCPT ); Wed, 9 May 2018 08:13:51 -0400 Received: from mail.toke.dk ([52.28.52.200]:41959 "EHLO mail.toke.dk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934653AbeEIMNt (ORCPT ); Wed, 9 May 2018 08:13:49 -0400 Subject: [PATCH 3/3] net: Dynamically allocate struct station_info DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=toke.dk; s=20161023; t=1525868025; bh=Togeb1XWfPmZCB1ZQE96vJTaZITiiWJRuCOP7kP8GEw=; h=Subject:From:To:Date:In-Reply-To:References:From; b=rlBtegIkC46C5JQkmP7mSaVYkGSfeqHrFkX8Z+epydM+sfUzBmI3ZeoWArK1wioqh j6hStyEtu1C638kYN/Rc5mJHtj+Feg8JSGxgZAWRj3E7K4oDQQwWYl0PElCjnFriJ/ T/YJDtrZ0o6OEi1EatJPH7MwngqooSwowc0VRZkLwFO1sVqM/W/9GRzy7QBxfZCVUW lzKPfsuXou8jSWAxBQyDNiQkXrHoPpRuV35eqKIkwwliSqPLRFjwosjHehpqzY6TjD /sNjYjkva7OyEaXvZFh03LOCiQd2vpFly2T7dSJiZT6YDkjaiAzxH1c8ef4didWIJO 1HjKLgMlC2rzg== From: Toke =?utf-8?q?H=C3=B8iland-J=C3=B8rgensen?= To: linux-wireless@vger.kernel.org Date: Wed, 09 May 2018 14:13:45 +0200 X-Clacks-Overhead: GNU Terry Pratchett Message-ID: <152586802515.18089.12700714478750075562.stgit@alrua-kau> In-Reply-To: <152586802501.18089.2502272945272741154.stgit@alrua-kau> References: <152586802501.18089.2502272945272741154.stgit@alrua-kau> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since the addition of the TXQ stats to cfg80211, the station_info struct has grown to be quite large, which results in warnings when allocated on the stack. Fix the affected places to do dynamic allocations instead. WARN_ON is used where the function has no way to signal errors to the caller. This patch applies the fix to batman-adv and wext-compat, while a separate patch fixes up the drivers. Fixes: 52539ca89f36 cfg80211: Expose TXQ stats and parameters to userspace Signed-off-by: Toke Høiland-Jørgensen --- net/batman-adv/bat_v_elp.c | 21 +++++++++++++++------ net/wireless/wext-compat.c | 29 +++++++++++++++++------------ 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 28687493599f..d2393ebc6af4 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -79,8 +79,9 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) struct batadv_hard_iface *hard_iface = neigh->if_incoming; struct ethtool_link_ksettings link_settings; struct net_device *real_netdev; - struct station_info sinfo; + struct station_info *sinfo; u32 throughput; + bool filled; int ret; /* if the user specified a customised value for this interface, then @@ -102,7 +103,17 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) if (!real_netdev) goto default_throughput; - ret = cfg80211_get_station(real_netdev, neigh->addr, &sinfo); + sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + if (!sinfo) + goto default_throughput; + + ret = cfg80211_get_station(real_netdev, neigh->addr, sinfo); + + /* just save these here instead of having complex free logic below */ + throughput = sinfo.expected_throughput / 100; + filled = !!(sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)); + + kfree(sinfo); dev_put(real_netdev); if (ret == -ENOENT) { @@ -112,12 +123,10 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) */ return 0; } - if (ret) - goto default_throughput; - if (!(sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT))) + if (ret || !filled) goto default_throughput; - return sinfo.expected_throughput / 100; + return throughput; } /* if not a wifi interface, check if this device provides data via diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 9e002df0f8d8..2038e3fb25fa 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -1300,7 +1300,7 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); /* we are under RTNL - globally locked - so can use static structs */ static struct iw_statistics wstats; - static struct station_info sinfo; + static struct station_info *sinfo; u8 bssid[ETH_ALEN]; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) @@ -1318,17 +1318,21 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); wdev_unlock(wdev); - memset(&sinfo, 0, sizeof(sinfo)); + sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + if (!sinfo) + return NULL; - if (rdev_get_station(rdev, dev, bssid, &sinfo)) + if (rdev_get_station(rdev, dev, bssid, sinfo)) { + kfree(sinfo); return NULL; + } memset(&wstats, 0, sizeof(wstats)); switch (rdev->wiphy.signal_type) { case CFG80211_SIGNAL_TYPE_MBM: - if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL)) { - int sig = sinfo.signal; + if (sinfo->filled & BIT(NL80211_STA_INFO_SIGNAL)) { + int sig = sinfo->signal; wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; wstats.qual.updated |= IW_QUAL_DBM; @@ -1341,11 +1345,11 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) break; } case CFG80211_SIGNAL_TYPE_UNSPEC: - if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL)) { + if (sinfo->filled & BIT(NL80211_STA_INFO_SIGNAL)) { wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; - wstats.qual.level = sinfo.signal; - wstats.qual.qual = sinfo.signal; + wstats.qual.level = sinfo->signal; + wstats.qual.qual = sinfo->signal; break; } default: @@ -1354,11 +1358,12 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) } wstats.qual.updated |= IW_QUAL_NOISE_INVALID; - if (sinfo.filled & BIT(NL80211_STA_INFO_RX_DROP_MISC)) - wstats.discard.misc = sinfo.rx_dropped_misc; - if (sinfo.filled & BIT(NL80211_STA_INFO_TX_FAILED)) - wstats.discard.retries = sinfo.tx_failed; + if (sinfo->filled & BIT(NL80211_STA_INFO_RX_DROP_MISC)) + wstats.discard.misc = sinfo->rx_dropped_misc; + if (sinfo->filled & BIT(NL80211_STA_INFO_TX_FAILED)) + wstats.discard.retries = sinfo->tx_failed; + kfree(sinfo); return &wstats; }