Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/960024/?format=api
{ "id": 960024, "url": "http://patchwork.ozlabs.org/api/patches/960024/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180820151233.14629-3-alice.michael@intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20180820151233.14629-3-alice.michael@intel.com>", "list_archive_url": null, "date": "2018-08-20T15:12:24", "name": "[next,S95,03/12] i40e: move ethtool stats boiler plate code to i40e_ethtool_stats.h", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "ce001bf3b6c32f00aee3c307809f630951663666", "submitter": { "id": 71123, "url": "http://patchwork.ozlabs.org/api/people/71123/?format=api", "name": "Michael, Alice", "email": "alice.michael@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180820151233.14629-3-alice.michael@intel.com/mbox/", "series": [ { "id": 61649, "url": "http://patchwork.ozlabs.org/api/series/61649/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=61649", "date": "2018-08-20T15:12:30", "name": null, "version": 1, "mbox": "http://patchwork.ozlabs.org/series/61649/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/960024/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/960024/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.136; helo=silver.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=intel.com" ], "Received": [ "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 41vVHg3hGlz9s4c\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 21 Aug 2018 09:23:59 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id 28CED23039;\n\tMon, 20 Aug 2018 23:23:58 +0000 (UTC)", "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id GSZbwPYCHMKr; Mon, 20 Aug 2018 23:23:51 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby silver.osuosl.org (Postfix) with ESMTP id 99BFD23027;\n\tMon, 20 Aug 2018 23:23:51 +0000 (UTC)", "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\tby ash.osuosl.org (Postfix) with ESMTP id E69921C16D3\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 20 Aug 2018 23:23:47 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id E4A4621561\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 20 Aug 2018 23:23:47 +0000 (UTC)", "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id AWLAQO3f2tX0 for <intel-wired-lan@lists.osuosl.org>;\n\tMon, 20 Aug 2018 23:23:46 +0000 (UTC)", "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby silver.osuosl.org (Postfix) with ESMTPS id 0C16022DB2\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 20 Aug 2018 23:23:46 +0000 (UTC)", "from orsmga001.jf.intel.com ([10.7.209.18])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t20 Aug 2018 16:23:45 -0700", "from alicemic-2.jf.intel.com ([10.166.16.121])\n\tby orsmga001.jf.intel.com with ESMTP; 20 Aug 2018 16:23:32 -0700" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.53,267,1531810800\"; d=\"scan'208\";a=\"83446369\"", "From": "Alice Michael <alice.michael@intel.com>", "To": "alice.michael@intel.com,\n\tintel-wired-lan@lists.osuosl.org", "Date": "Mon, 20 Aug 2018 08:12:24 -0700", "Message-Id": "<20180820151233.14629-3-alice.michael@intel.com>", "X-Mailer": "git-send-email 2.9.5", "In-Reply-To": "<20180820151233.14629-1-alice.michael@intel.com>", "References": "<20180820151233.14629-1-alice.michael@intel.com>", "Subject": "[Intel-wired-lan] [next PATCH S95 03/12] i40e: move ethtool stats\n\tboiler plate code to i40e_ethtool_stats.h", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.24", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "From: Jacob Keller <jacob.e.keller@intel.com>\n\nMove the boiler plate structures and helper functions we recently\nadded into their own header file, so that the complete collection is\nlocated together.\n\nSigned-off-by: Jacob Keller <jacob.e.keller@intel.com>\n---\n drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 182 +----------------\n .../net/ethernet/intel/i40e/i40e_ethtool_stats.h | 221 +++++++++++++++++++++\n 2 files changed, 222 insertions(+), 181 deletions(-)\n create mode 100644 drivers/net/ethernet/intel/i40e/i40e_ethtool_stats.h", "diff": "diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\nindex 9ac41c8..ecc30524 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\n@@ -6,25 +6,8 @@\n #include \"i40e.h\"\n #include \"i40e_diag.h\"\n \n-struct i40e_stats {\n-\t/* The stat_string is expected to be a format string formatted using\n-\t * vsnprintf by i40e_add_stat_strings. Every member of a stats array\n-\t * should use the same format specifiers as they will be formatted\n-\t * using the same variadic arguments.\n-\t */\n-\tchar stat_string[ETH_GSTRING_LEN];\n-\tint sizeof_stat;\n-\tint stat_offset;\n-};\n-\n-#define I40E_STAT(_type, _name, _stat) { \\\n-\t.stat_string = _name, \\\n-\t.sizeof_stat = FIELD_SIZEOF(_type, _stat), \\\n-\t.stat_offset = offsetof(_type, _stat) \\\n-}\n+#include \"i40e_ethtool_stats.h\"\n \n-#define I40E_NETDEV_STAT(_net_stat) \\\n-\tI40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)\n #define I40E_PF_STAT(_name, _stat) \\\n \tI40E_STAT(struct i40e_pf, _name, _stat)\n #define I40E_VSI_STAT(_name, _stat) \\\n@@ -173,11 +156,6 @@ static const struct i40e_stats i40e_gstrings_pfc_stats[] = {\n \tI40E_PFC_STAT(\"port.rx_priority_%u_xon_2_xoff\", priority_xon_2_xoff),\n };\n \n-static const struct i40e_stats i40e_gstrings_queue_stats[] = {\n-\tI40E_QUEUE_STAT(\"%s-%u.packets\", stats.packets),\n-\tI40E_QUEUE_STAT(\"%s-%u.bytes\", stats.bytes),\n-};\n-\n #define I40E_NETDEV_STATS_LEN\tARRAY_SIZE(i40e_gstrings_net_stats)\n \n #define I40E_MISC_STATS_LEN\tARRAY_SIZE(i40e_gstrings_misc_stats)\n@@ -1750,128 +1728,6 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset)\n }\n \n /**\n- * i40e_add_one_ethtool_stat - copy the stat into the supplied buffer\n- * @data: location to store the stat value\n- * @pointer: basis for where to copy from\n- * @stat: the stat definition\n- *\n- * Copies the stat data defined by the pointer and stat structure pair into\n- * the memory supplied as data. Used to implement i40e_add_ethtool_stats and\n- * i40e_add_queue_stats. If the pointer is null, data will be zero'd.\n- */\n-static inline void\n-i40e_add_one_ethtool_stat(u64 *data, void *pointer,\n-\t\t\t const struct i40e_stats *stat)\n-{\n-\tchar *p;\n-\n-\tif (!pointer) {\n-\t\t/* ensure that the ethtool data buffer is zero'd for any stats\n-\t\t * which don't have a valid pointer.\n-\t\t */\n-\t\t*data = 0;\n-\t\treturn;\n-\t}\n-\n-\tp = (char *)pointer + stat->stat_offset;\n-\tswitch (stat->sizeof_stat) {\n-\tcase sizeof(u64):\n-\t\t*data = *((u64 *)p);\n-\t\tbreak;\n-\tcase sizeof(u32):\n-\t\t*data = *((u32 *)p);\n-\t\tbreak;\n-\tcase sizeof(u16):\n-\t\t*data = *((u16 *)p);\n-\t\tbreak;\n-\tcase sizeof(u8):\n-\t\t*data = *((u8 *)p);\n-\t\tbreak;\n-\tdefault:\n-\t\tWARN_ONCE(1, \"unexpected stat size for %s\",\n-\t\t\t stat->stat_string);\n-\t\t*data = 0;\n-\t}\n-}\n-\n-/**\n- * __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer\n- * @data: ethtool stats buffer\n- * @pointer: location to copy stats from\n- * @stats: array of stats to copy\n- * @size: the size of the stats definition\n- *\n- * Copy the stats defined by the stats array using the pointer as a base into\n- * the data buffer supplied by ethtool. Updates the data pointer to point to\n- * the next empty location for successive calls to __i40e_add_ethtool_stats.\n- * If pointer is null, set the data values to zero and update the pointer to\n- * skip these stats.\n- **/\n-static inline void\n-__i40e_add_ethtool_stats(u64 **data, void *pointer,\n-\t\t\t const struct i40e_stats stats[],\n-\t\t\t const unsigned int size)\n-{\n-\tunsigned int i;\n-\n-\tfor (i = 0; i < size; i++)\n-\t\ti40e_add_one_ethtool_stat((*data)++, pointer, &stats[i]);\n-}\n-\n-/**\n- * i40e_add_ethtool_stats - copy stats into ethtool supplied buffer\n- * @data: ethtool stats buffer\n- * @pointer: location where stats are stored\n- * @stats: static const array of stat definitions\n- *\n- * Macro to ease the use of __i40e_add_ethtool_stats by taking a static\n- * constant stats array and passing the ARRAY_SIZE(). This avoids typos by\n- * ensuring that we pass the size associated with the given stats array.\n- * Assumes that stats is an array.\n- **/\n-#define i40e_add_ethtool_stats(data, pointer, stats) \\\n-\t__i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))\n-\n-/**\n- * i40e_add_queue_stats - copy queue statistics into supplied buffer\n- * @data: ethtool stats buffer\n- * @ring: the ring to copy\n- *\n- * Queue statistics must be copied while protected by\n- * u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats.\n- * Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the\n- * ring pointer is null, zero out the queue stat values and update the data\n- * pointer. Otherwise safely copy the stats from the ring into the supplied\n- * buffer and update the data pointer when finished.\n- *\n- * This function expects to be called while under rcu_read_lock().\n- **/\n-static inline void\n-i40e_add_queue_stats(u64 **data, struct i40e_ring *ring)\n-{\n-\tconst unsigned int size = ARRAY_SIZE(i40e_gstrings_queue_stats);\n-\tconst struct i40e_stats *stats = i40e_gstrings_queue_stats;\n-\tunsigned int start;\n-\tunsigned int i;\n-\n-\t/* To avoid invalid statistics values, ensure that we keep retrying\n-\t * the copy until we get a consistent value according to\n-\t * u64_stats_fetch_retry_irq. But first, make sure our ring is\n-\t * non-null before attempting to access its syncp.\n-\t */\n-\tdo {\n-\t\tstart = !ring ? 0 : u64_stats_fetch_begin_irq(&ring->syncp);\n-\t\tfor (i = 0; i < size; i++) {\n-\t\t\ti40e_add_one_ethtool_stat(&(*data)[i], ring,\n-\t\t\t\t\t\t &stats[i]);\n-\t\t}\n-\t} while (ring && u64_stats_fetch_retry_irq(&ring->syncp, start));\n-\n-\t/* Once we successfully copy the stats in, update the data pointer */\n-\tdata += size;\n-}\n-\n-/**\n * i40e_get_pfc_stats - copy HW PFC statistics to formatted structure\n * @pf: the PF device structure\n * @i: the priority value to copy\n@@ -1966,42 +1822,6 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,\n }\n \n /**\n- * __i40e_add_stat_strings - copy stat strings into ethtool buffer\n- * @p: ethtool supplied buffer\n- * @stats: stat definitions array\n- * @size: size of the stats array\n- *\n- * Format and copy the strings described by stats into the buffer pointed at\n- * by p.\n- **/\n-static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],\n-\t\t\t\t const unsigned int size, ...)\n-{\n-\tunsigned int i;\n-\n-\tfor (i = 0; i < size; i++) {\n-\t\tva_list args;\n-\n-\t\tva_start(args, size);\n-\t\tvsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);\n-\t\t*p += ETH_GSTRING_LEN;\n-\t\tva_end(args);\n-\t}\n-}\n-\n-/**\n- * 40e_add_stat_strings - copy stat strings into ethtool buffer\n- * @p: ethtool supplied buffer\n- * @stats: stat definitions array\n- *\n- * Format and copy the strings described by the const static stats value into\n- * the buffer pointed at by p. Assumes that stats can have ARRAY_SIZE called\n- * for it.\n- **/\n-#define i40e_add_stat_strings(p, stats, ...) \\\n-\t__i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)\n-\n-/**\n * i40e_get_stat_strings - copy stat strings into supplied buffer\n * @netdev: the netdev to collect strings for\n * @data: supplied buffer to copy strings into\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool_stats.h b/drivers/net/ethernet/intel/i40e/i40e_ethtool_stats.h\nnew file mode 100644\nindex 0000000..0290ade\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool_stats.h\n@@ -0,0 +1,221 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+/* Copyright(c) 2013 - 2018 Intel Corporation. */\n+\n+/* ethtool statistics helpers */\n+\n+/**\n+ * struct i40e_stats - definition for an ethtool statistic\n+ * @stat_string: statistic name to display in ethtool -S output\n+ * @sizeof_stat: the sizeof() the stat, must be no greater than sizeof(u64)\n+ * @stat_offset: offsetof() the stat from a base pointer\n+ *\n+ * This structure defines a statistic to be added to the ethtool stats buffer.\n+ * It defines a statistic as offset from a common base pointer. Stats should\n+ * be defined in constant arrays using the I40E_STAT macro, with every element\n+ * of the array using the same _type for calculating the sizeof_stat and\n+ * stat_offset.\n+ *\n+ * The @sizeof_stat is expected to be sizeof(u8), sizeof(u16), sizeof(u32) or\n+ * sizeof(u64). Other sizes are not expected and will produce a WARN_ONCE from\n+ * the i40e_add_ethtool_stat() helper function.\n+ *\n+ * The @stat_string is interpreted as a format string, allowing formatted\n+ * values to be inserted while looping over multiple structures for a given\n+ * statistics array. Thus, every statistic string in an array should have the\n+ * same type and number of format specifiers, to be formatted by variadic\n+ * arguments to the i40e_add_stat_string() helper function.\n+ **/\n+struct i40e_stats {\n+\tchar stat_string[ETH_GSTRING_LEN];\n+\tint sizeof_stat;\n+\tint stat_offset;\n+};\n+\n+/* Helper macro to define an i40e_stat structure with proper size and type.\n+ * Use this when defining constant statistics arrays. Note that @_type expects\n+ * only a type name and is used multiple times.\n+ */\n+#define I40E_STAT(_type, _name, _stat) { \\\n+\t.stat_string = _name, \\\n+\t.sizeof_stat = FIELD_SIZEOF(_type, _stat), \\\n+\t.stat_offset = offsetof(_type, _stat) \\\n+}\n+\n+/* Helper macro for defining some statistics directly copied from the netdev\n+ * stats structure.\n+ */\n+#define I40E_NETDEV_STAT(_net_stat) \\\n+\tI40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)\n+\n+/* Helper macro for defining some statistics related to queues */\n+#define I40E_QUEUE_STAT(_name, _stat) \\\n+\tI40E_STAT(struct i40e_ring, _name, _stat)\n+\n+/* Stats associated with a Tx or Rx ring */\n+static const struct i40e_stats i40e_gstrings_queue_stats[] = {\n+\tI40E_QUEUE_STAT(\"%s-%u.packets\", stats.packets),\n+\tI40E_QUEUE_STAT(\"%s-%u.bytes\", stats.bytes),\n+};\n+\n+/**\n+ * i40e_add_one_ethtool_stat - copy the stat into the supplied buffer\n+ * @data: location to store the stat value\n+ * @pointer: basis for where to copy from\n+ * @stat: the stat definition\n+ *\n+ * Copies the stat data defined by the pointer and stat structure pair into\n+ * the memory supplied as data. Used to implement i40e_add_ethtool_stats and\n+ * i40e_add_queue_stats. If the pointer is null, data will be zero'd.\n+ */\n+static inline void\n+i40e_add_one_ethtool_stat(u64 *data, void *pointer,\n+\t\t\t const struct i40e_stats *stat)\n+{\n+\tchar *p;\n+\n+\tif (!pointer) {\n+\t\t/* ensure that the ethtool data buffer is zero'd for any stats\n+\t\t * which don't have a valid pointer.\n+\t\t */\n+\t\t*data = 0;\n+\t\treturn;\n+\t}\n+\n+\tp = (char *)pointer + stat->stat_offset;\n+\tswitch (stat->sizeof_stat) {\n+\tcase sizeof(u64):\n+\t\t*data = *((u64 *)p);\n+\t\tbreak;\n+\tcase sizeof(u32):\n+\t\t*data = *((u32 *)p);\n+\t\tbreak;\n+\tcase sizeof(u16):\n+\t\t*data = *((u16 *)p);\n+\t\tbreak;\n+\tcase sizeof(u8):\n+\t\t*data = *((u8 *)p);\n+\t\tbreak;\n+\tdefault:\n+\t\tWARN_ONCE(1, \"unexpected stat size for %s\",\n+\t\t\t stat->stat_string);\n+\t\t*data = 0;\n+\t}\n+}\n+\n+/**\n+ * __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer\n+ * @data: ethtool stats buffer\n+ * @pointer: location to copy stats from\n+ * @stats: array of stats to copy\n+ * @size: the size of the stats definition\n+ *\n+ * Copy the stats defined by the stats array using the pointer as a base into\n+ * the data buffer supplied by ethtool. Updates the data pointer to point to\n+ * the next empty location for successive calls to __i40e_add_ethtool_stats.\n+ * If pointer is null, set the data values to zero and update the pointer to\n+ * skip these stats.\n+ **/\n+static inline void\n+__i40e_add_ethtool_stats(u64 **data, void *pointer,\n+\t\t\t const struct i40e_stats stats[],\n+\t\t\t const unsigned int size)\n+{\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < size; i++)\n+\t\ti40e_add_one_ethtool_stat((*data)++, pointer, &stats[i]);\n+}\n+\n+/**\n+ * i40e_add_ethtool_stats - copy stats into ethtool supplied buffer\n+ * @data: ethtool stats buffer\n+ * @pointer: location where stats are stored\n+ * @stats: static const array of stat definitions\n+ *\n+ * Macro to ease the use of __i40e_add_ethtool_stats by taking a static\n+ * constant stats array and passing the ARRAY_SIZE(). This avoids typos by\n+ * ensuring that we pass the size associated with the given stats array.\n+ *\n+ * The parameter @stats is evaluated twice, so parameters with side effects\n+ * should be avoided.\n+ **/\n+#define i40e_add_ethtool_stats(data, pointer, stats) \\\n+\t__i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))\n+\n+/**\n+ * i40e_add_queue_stats - copy queue statistics into supplied buffer\n+ * @data: ethtool stats buffer\n+ * @ring: the ring to copy\n+ *\n+ * Queue statistics must be copied while protected by\n+ * u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats.\n+ * Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the\n+ * ring pointer is null, zero out the queue stat values and update the data\n+ * pointer. Otherwise safely copy the stats from the ring into the supplied\n+ * buffer and update the data pointer when finished.\n+ *\n+ * This function expects to be called while under rcu_read_lock().\n+ **/\n+static inline void\n+i40e_add_queue_stats(u64 **data, struct i40e_ring *ring)\n+{\n+\tconst unsigned int size = ARRAY_SIZE(i40e_gstrings_queue_stats);\n+\tconst struct i40e_stats *stats = i40e_gstrings_queue_stats;\n+\tunsigned int start;\n+\tunsigned int i;\n+\n+\t/* To avoid invalid statistics values, ensure that we keep retrying\n+\t * the copy until we get a consistent value according to\n+\t * u64_stats_fetch_retry_irq. But first, make sure our ring is\n+\t * non-null before attempting to access its syncp.\n+\t */\n+\tdo {\n+\t\tstart = !ring ? 0 : u64_stats_fetch_begin_irq(&ring->syncp);\n+\t\tfor (i = 0; i < size; i++) {\n+\t\t\ti40e_add_one_ethtool_stat(&(*data)[i], ring,\n+\t\t\t\t\t\t &stats[i]);\n+\t\t}\n+\t} while (ring && u64_stats_fetch_retry_irq(&ring->syncp, start));\n+\n+\t/* Once we successfully copy the stats in, update the data pointer */\n+\t*data += size;\n+}\n+\n+/**\n+ * __i40e_add_stat_strings - copy stat strings into ethtool buffer\n+ * @p: ethtool supplied buffer\n+ * @stats: stat definitions array\n+ * @size: size of the stats array\n+ *\n+ * Format and copy the strings described by stats into the buffer pointed at\n+ * by p.\n+ **/\n+static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],\n+\t\t\t\t const unsigned int size, ...)\n+{\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < size; i++) {\n+\t\tva_list args;\n+\n+\t\tva_start(args, size);\n+\t\tvsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);\n+\t\t*p += ETH_GSTRING_LEN;\n+\t\tva_end(args);\n+\t}\n+}\n+\n+/**\n+ * 40e_add_stat_strings - copy stat strings into ethtool buffer\n+ * @p: ethtool supplied buffer\n+ * @stats: stat definitions array\n+ *\n+ * Format and copy the strings described by the const static stats value into\n+ * the buffer pointed at by p.\n+ *\n+ * The parameter @stats is evaluated twice, so parameters with side effects\n+ * should be avoided. Additionally, stats must be an array such that\n+ * ARRAY_SIZE can be called on it.\n+ **/\n+#define i40e_add_stat_strings(p, stats, ...) \\\n+\t__i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)\n", "prefixes": [ "next", "S95", "03/12" ] }