From patchwork Thu Apr 19 18:17:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Greear X-Patchwork-Id: 10351439 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 71F1160365 for ; Thu, 19 Apr 2018 18:18:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 635F42434C for ; Thu, 19 Apr 2018 18:18:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5815628382; Thu, 19 Apr 2018 18:18:29 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2F9A428397 for ; Thu, 19 Apr 2018 18:18:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=lu3j1Q2HvJtv1AQ790aIY/8eBMq46DQ8vSvySqJuzq8=; b=MWd Nu9oCmIAQ5bPazWdz+j9E+Azg+YIWtOeK+Gh8M92h7jJLaqsD5NXzOyudf4HUjOTtvwy0cNMwhDod HvZTy9PvUnL7iRXMxVZyj+zzpAa9FUqdUWK1Q/kBB7YqApCXDID1H+DY3x3Hjbxqu1xFPC4wRauqo r/Ghq29oDpDfttgyNtIdmQb4f31j+2pZPxb/W2sLsUr19MnUX79XeihNUdvHHcZuP1KHoHceXjaBv xaNFLblwQh2yTFZnEOHsJ1GOjLk6+WAaA6FuOz0wcvLAp+usiQYnTcK7+zcr+ni0EWBuR+B5o8Vms ispBxaqyXISOfbQM8GtROwv7lNZhSwg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1f9E8Q-0002o1-Qk; Thu, 19 Apr 2018 18:18:18 +0000 Received: from mail2.candelatech.com ([208.74.158.173]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1f9E8F-0002jj-G3 for ath10k@lists.infradead.org; Thu, 19 Apr 2018 18:18:10 +0000 Received: from ben-dt3.candelatech.com (firewall.candelatech.com [50.251.239.81]) by mail2.candelatech.com (Postfix) with ESMTP id 00FDE40B146; Thu, 19 Apr 2018 11:17:52 -0700 (PDT) From: greearb@candelatech.com To: netdev@vger.kernel.org Subject: [PATCH v2 1/3] ethtool: Support ETHTOOL_GSTATS2 command. Date: Thu, 19 Apr 2018 11:17:41 -0700 Message-Id: <1524161863-30860-1-git-send-email-greearb@candelatech.com> X-Mailer: git-send-email 2.4.11 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180419_111807_614724_3A1E4653 X-CRM114-Status: GOOD ( 13.96 ) X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ben Greear , linux-wireless@vger.kernel.org, ath10k@lists.infradead.org MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ben Greear This is similar to ETHTOOL_GSTATS, but it allows you to specify flags. These flags can be used by the driver to decrease the amount of stats refreshed. In particular, this helps with ath10k since getting the firmware stats can be slow. Signed-off-by: Ben Greear --- v2: Change flag names to ETHTOOL_GS_NO_REFRESH_FW, ETHTOOL_GS2_REFRESH_ALL. include/linux/ethtool.h | 12 ++++++++++++ include/uapi/linux/ethtool.h | 11 +++++++++++ net/core/ethtool.c | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ebe4181..c90bc6f6 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -243,6 +243,15 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, * @get_ethtool_stats: Return extended statistics about the device. * This is only useful if the device maintains statistics not * included in &struct rtnl_link_stats64. + * @get_ethtool_stats2: Return extended statistics about the device. + * This is only useful if the device maintains statistics not + * included in &struct rtnl_link_stats64. + * Takes a flags argument: 0 means all (same as get_ethtool_stats), + * 0x1 (ETHTOOL_GS2_NO_REFRESH_FW) means skip refreshing firmware stats. + * Other flags are reserved for now. + * Same number of stats will be returned, but some of them might + * not be as accurate/refreshed. This is to allow not querying + * firmware or other expensive-to-read stats, for instance. * @begin: Function to be called before any other operation. Returns a * negative error code or zero. * @complete: Function to be called after any other operation except @@ -355,6 +364,9 @@ struct ethtool_ops { int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state); void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); + void (*get_ethtool_stats2)(struct net_device *dev, + struct ethtool_stats *gstats, u64 *data, + u32 flags); int (*begin)(struct net_device *); void (*complete)(struct net_device *); u32 (*get_priv_flags)(struct net_device *); diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 4ca65b5..75c753d 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -1396,11 +1396,22 @@ enum ethtool_fec_config_bits { #define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */ #define ETHTOOL_GFECPARAM 0x00000050 /* Get FEC settings */ #define ETHTOOL_SFECPARAM 0x00000051 /* Set FEC settings */ +#define ETHTOOL_GSTATS2 0x00000052 /* get NIC-specific statistics + * with ability to specify flags. + * See ETHTOOL_GS2* below. + */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET #define SPARC_ETH_SSET ETHTOOL_SSET +/* GSTATS2 flags */ +#define ETHTOOL_GS2_REFRESH_ALL (0) /* default is to update all stats */ +#define ETHTOOL_GS2_NO_REFRESH_FW (1<<0) /* Skip refreshing stats that probe + * firmware, and thus are + * slow/expensive. + */ + /* Link mode bit indices */ enum ethtool_link_mode_bit_indices { ETHTOOL_LINK_MODE_10baseT_Half_BIT = 0, diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 03416e6..dd16f15 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1952,16 +1952,14 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) return rc; } -static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) +static int _ethtool_get_stats(struct net_device *dev, void __user *useraddr, + u32 flags) { struct ethtool_stats stats; const struct ethtool_ops *ops = dev->ethtool_ops; u64 *data; int ret, n_stats; - if (!ops->get_ethtool_stats || !ops->get_sset_count) - return -EOPNOTSUPP; - n_stats = ops->get_sset_count(dev, ETH_SS_STATS); if (n_stats < 0) return n_stats; @@ -1976,7 +1974,10 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) if (n_stats && !data) return -ENOMEM; - ops->get_ethtool_stats(dev, &stats, data); + if (flags != ETHTOOL_GS2_REFRESH_ALL) + ops->get_ethtool_stats2(dev, &stats, data, flags); + else + ops->get_ethtool_stats(dev, &stats, data); ret = -EFAULT; if (copy_to_user(useraddr, &stats, sizeof(stats))) @@ -1991,6 +1992,31 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) return ret; } +static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) +{ + const struct ethtool_ops *ops = dev->ethtool_ops; + + if (!ops->get_ethtool_stats || !ops->get_sset_count) + return -EOPNOTSUPP; + return _ethtool_get_stats(dev, useraddr, ETHTOOL_GS2_REFRESH_ALL); +} + +static int ethtool_get_stats2(struct net_device *dev, void __user *useraddr) +{ + struct ethtool_stats stats; + const struct ethtool_ops *ops = dev->ethtool_ops; + u32 flags = 0; + + if (!ops->get_ethtool_stats2 || !ops->get_sset_count) + return -EOPNOTSUPP; + + if (copy_from_user(&stats, useraddr, sizeof(stats))) + return -EFAULT; + + flags = stats.n_stats; + return _ethtool_get_stats(dev, useraddr, flags); +} + static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr) { struct ethtool_stats stats; @@ -2632,6 +2658,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GSSET_INFO: case ETHTOOL_GSTRINGS: case ETHTOOL_GSTATS: + case ETHTOOL_GSTATS2: case ETHTOOL_GPHYSTATS: case ETHTOOL_GTSO: case ETHTOOL_GPERMADDR: @@ -2742,6 +2769,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GSTATS: rc = ethtool_get_stats(dev, useraddr); break; + case ETHTOOL_GSTATS2: + rc = ethtool_get_stats2(dev, useraddr); + break; case ETHTOOL_GPERMADDR: rc = ethtool_get_perm_addr(dev, useraddr); break;