mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-21 18:38:46 +07:00
i40e: move ethtool stats boiler plate code to i40e_ethtool_stats.h
Move the boiler plate structures and helper functions we recently added into their own header file, so that the complete collection is located together. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
4b59938b20
commit
8fd75c58a0
@ -6,25 +6,8 @@
|
||||
#include "i40e.h"
|
||||
#include "i40e_diag.h"
|
||||
|
||||
struct i40e_stats {
|
||||
/* The stat_string is expected to be a format string formatted using
|
||||
* vsnprintf by i40e_add_stat_strings. Every member of a stats array
|
||||
* should use the same format specifiers as they will be formatted
|
||||
* using the same variadic arguments.
|
||||
*/
|
||||
char stat_string[ETH_GSTRING_LEN];
|
||||
int sizeof_stat;
|
||||
int stat_offset;
|
||||
};
|
||||
#include "i40e_ethtool_stats.h"
|
||||
|
||||
#define I40E_STAT(_type, _name, _stat) { \
|
||||
.stat_string = _name, \
|
||||
.sizeof_stat = FIELD_SIZEOF(_type, _stat), \
|
||||
.stat_offset = offsetof(_type, _stat) \
|
||||
}
|
||||
|
||||
#define I40E_NETDEV_STAT(_net_stat) \
|
||||
I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)
|
||||
#define I40E_PF_STAT(_name, _stat) \
|
||||
I40E_STAT(struct i40e_pf, _name, _stat)
|
||||
#define I40E_VSI_STAT(_name, _stat) \
|
||||
@ -173,11 +156,6 @@ static const struct i40e_stats i40e_gstrings_pfc_stats[] = {
|
||||
I40E_PFC_STAT("port.rx_priority_%u_xon_2_xoff", priority_xon_2_xoff),
|
||||
};
|
||||
|
||||
static const struct i40e_stats i40e_gstrings_queue_stats[] = {
|
||||
I40E_QUEUE_STAT("%s-%u.packets", stats.packets),
|
||||
I40E_QUEUE_STAT("%s-%u.bytes", stats.bytes),
|
||||
};
|
||||
|
||||
#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
|
||||
|
||||
#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
|
||||
@ -1749,128 +1727,6 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_add_one_ethtool_stat - copy the stat into the supplied buffer
|
||||
* @data: location to store the stat value
|
||||
* @pointer: basis for where to copy from
|
||||
* @stat: the stat definition
|
||||
*
|
||||
* Copies the stat data defined by the pointer and stat structure pair into
|
||||
* the memory supplied as data. Used to implement i40e_add_ethtool_stats and
|
||||
* i40e_add_queue_stats. If the pointer is null, data will be zero'd.
|
||||
*/
|
||||
static inline void
|
||||
i40e_add_one_ethtool_stat(u64 *data, void *pointer,
|
||||
const struct i40e_stats *stat)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!pointer) {
|
||||
/* ensure that the ethtool data buffer is zero'd for any stats
|
||||
* which don't have a valid pointer.
|
||||
*/
|
||||
*data = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
p = (char *)pointer + stat->stat_offset;
|
||||
switch (stat->sizeof_stat) {
|
||||
case sizeof(u64):
|
||||
*data = *((u64 *)p);
|
||||
break;
|
||||
case sizeof(u32):
|
||||
*data = *((u32 *)p);
|
||||
break;
|
||||
case sizeof(u16):
|
||||
*data = *((u16 *)p);
|
||||
break;
|
||||
case sizeof(u8):
|
||||
*data = *((u8 *)p);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "unexpected stat size for %s",
|
||||
stat->stat_string);
|
||||
*data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer
|
||||
* @data: ethtool stats buffer
|
||||
* @pointer: location to copy stats from
|
||||
* @stats: array of stats to copy
|
||||
* @size: the size of the stats definition
|
||||
*
|
||||
* Copy the stats defined by the stats array using the pointer as a base into
|
||||
* the data buffer supplied by ethtool. Updates the data pointer to point to
|
||||
* the next empty location for successive calls to __i40e_add_ethtool_stats.
|
||||
* If pointer is null, set the data values to zero and update the pointer to
|
||||
* skip these stats.
|
||||
**/
|
||||
static inline void
|
||||
__i40e_add_ethtool_stats(u64 **data, void *pointer,
|
||||
const struct i40e_stats stats[],
|
||||
const unsigned int size)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
i40e_add_one_ethtool_stat((*data)++, pointer, &stats[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_add_ethtool_stats - copy stats into ethtool supplied buffer
|
||||
* @data: ethtool stats buffer
|
||||
* @pointer: location where stats are stored
|
||||
* @stats: static const array of stat definitions
|
||||
*
|
||||
* Macro to ease the use of __i40e_add_ethtool_stats by taking a static
|
||||
* constant stats array and passing the ARRAY_SIZE(). This avoids typos by
|
||||
* ensuring that we pass the size associated with the given stats array.
|
||||
* Assumes that stats is an array.
|
||||
**/
|
||||
#define i40e_add_ethtool_stats(data, pointer, stats) \
|
||||
__i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))
|
||||
|
||||
/**
|
||||
* i40e_add_queue_stats - copy queue statistics into supplied buffer
|
||||
* @data: ethtool stats buffer
|
||||
* @ring: the ring to copy
|
||||
*
|
||||
* Queue statistics must be copied while protected by
|
||||
* u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats.
|
||||
* Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the
|
||||
* ring pointer is null, zero out the queue stat values and update the data
|
||||
* pointer. Otherwise safely copy the stats from the ring into the supplied
|
||||
* buffer and update the data pointer when finished.
|
||||
*
|
||||
* This function expects to be called while under rcu_read_lock().
|
||||
**/
|
||||
static inline void
|
||||
i40e_add_queue_stats(u64 **data, struct i40e_ring *ring)
|
||||
{
|
||||
const unsigned int size = ARRAY_SIZE(i40e_gstrings_queue_stats);
|
||||
const struct i40e_stats *stats = i40e_gstrings_queue_stats;
|
||||
unsigned int start;
|
||||
unsigned int i;
|
||||
|
||||
/* To avoid invalid statistics values, ensure that we keep retrying
|
||||
* the copy until we get a consistent value according to
|
||||
* u64_stats_fetch_retry_irq. But first, make sure our ring is
|
||||
* non-null before attempting to access its syncp.
|
||||
*/
|
||||
do {
|
||||
start = !ring ? 0 : u64_stats_fetch_begin_irq(&ring->syncp);
|
||||
for (i = 0; i < size; i++) {
|
||||
i40e_add_one_ethtool_stat(&(*data)[i], ring,
|
||||
&stats[i]);
|
||||
}
|
||||
} while (ring && u64_stats_fetch_retry_irq(&ring->syncp, start));
|
||||
|
||||
/* Once we successfully copy the stats in, update the data pointer */
|
||||
data += size;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_get_pfc_stats - copy HW PFC statistics to formatted structure
|
||||
* @pf: the PF device structure
|
||||
@ -1965,42 +1821,6 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
|
||||
"ethtool stats count mismatch!");
|
||||
}
|
||||
|
||||
/**
|
||||
* __i40e_add_stat_strings - copy stat strings into ethtool buffer
|
||||
* @p: ethtool supplied buffer
|
||||
* @stats: stat definitions array
|
||||
* @size: size of the stats array
|
||||
*
|
||||
* Format and copy the strings described by stats into the buffer pointed at
|
||||
* by p.
|
||||
**/
|
||||
static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],
|
||||
const unsigned int size, ...)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, size);
|
||||
vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);
|
||||
*p += ETH_GSTRING_LEN;
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 40e_add_stat_strings - copy stat strings into ethtool buffer
|
||||
* @p: ethtool supplied buffer
|
||||
* @stats: stat definitions array
|
||||
*
|
||||
* Format and copy the strings described by the const static stats value into
|
||||
* the buffer pointed at by p. Assumes that stats can have ARRAY_SIZE called
|
||||
* for it.
|
||||
**/
|
||||
#define i40e_add_stat_strings(p, stats, ...) \
|
||||
__i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* i40e_get_stat_strings - copy stat strings into supplied buffer
|
||||
* @netdev: the netdev to collect strings for
|
||||
|
221
drivers/net/ethernet/intel/i40e/i40e_ethtool_stats.h
Normal file
221
drivers/net/ethernet/intel/i40e/i40e_ethtool_stats.h
Normal file
@ -0,0 +1,221 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright(c) 2013 - 2018 Intel Corporation. */
|
||||
|
||||
/* ethtool statistics helpers */
|
||||
|
||||
/**
|
||||
* struct i40e_stats - definition for an ethtool statistic
|
||||
* @stat_string: statistic name to display in ethtool -S output
|
||||
* @sizeof_stat: the sizeof() the stat, must be no greater than sizeof(u64)
|
||||
* @stat_offset: offsetof() the stat from a base pointer
|
||||
*
|
||||
* This structure defines a statistic to be added to the ethtool stats buffer.
|
||||
* It defines a statistic as offset from a common base pointer. Stats should
|
||||
* be defined in constant arrays using the I40E_STAT macro, with every element
|
||||
* of the array using the same _type for calculating the sizeof_stat and
|
||||
* stat_offset.
|
||||
*
|
||||
* The @sizeof_stat is expected to be sizeof(u8), sizeof(u16), sizeof(u32) or
|
||||
* sizeof(u64). Other sizes are not expected and will produce a WARN_ONCE from
|
||||
* the i40e_add_ethtool_stat() helper function.
|
||||
*
|
||||
* The @stat_string is interpreted as a format string, allowing formatted
|
||||
* values to be inserted while looping over multiple structures for a given
|
||||
* statistics array. Thus, every statistic string in an array should have the
|
||||
* same type and number of format specifiers, to be formatted by variadic
|
||||
* arguments to the i40e_add_stat_string() helper function.
|
||||
**/
|
||||
struct i40e_stats {
|
||||
char stat_string[ETH_GSTRING_LEN];
|
||||
int sizeof_stat;
|
||||
int stat_offset;
|
||||
};
|
||||
|
||||
/* Helper macro to define an i40e_stat structure with proper size and type.
|
||||
* Use this when defining constant statistics arrays. Note that @_type expects
|
||||
* only a type name and is used multiple times.
|
||||
*/
|
||||
#define I40E_STAT(_type, _name, _stat) { \
|
||||
.stat_string = _name, \
|
||||
.sizeof_stat = FIELD_SIZEOF(_type, _stat), \
|
||||
.stat_offset = offsetof(_type, _stat) \
|
||||
}
|
||||
|
||||
/* Helper macro for defining some statistics directly copied from the netdev
|
||||
* stats structure.
|
||||
*/
|
||||
#define I40E_NETDEV_STAT(_net_stat) \
|
||||
I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)
|
||||
|
||||
/* Helper macro for defining some statistics related to queues */
|
||||
#define I40E_QUEUE_STAT(_name, _stat) \
|
||||
I40E_STAT(struct i40e_ring, _name, _stat)
|
||||
|
||||
/* Stats associated with a Tx or Rx ring */
|
||||
static const struct i40e_stats i40e_gstrings_queue_stats[] = {
|
||||
I40E_QUEUE_STAT("%s-%u.packets", stats.packets),
|
||||
I40E_QUEUE_STAT("%s-%u.bytes", stats.bytes),
|
||||
};
|
||||
|
||||
/**
|
||||
* i40e_add_one_ethtool_stat - copy the stat into the supplied buffer
|
||||
* @data: location to store the stat value
|
||||
* @pointer: basis for where to copy from
|
||||
* @stat: the stat definition
|
||||
*
|
||||
* Copies the stat data defined by the pointer and stat structure pair into
|
||||
* the memory supplied as data. Used to implement i40e_add_ethtool_stats and
|
||||
* i40e_add_queue_stats. If the pointer is null, data will be zero'd.
|
||||
*/
|
||||
static inline void
|
||||
i40e_add_one_ethtool_stat(u64 *data, void *pointer,
|
||||
const struct i40e_stats *stat)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!pointer) {
|
||||
/* ensure that the ethtool data buffer is zero'd for any stats
|
||||
* which don't have a valid pointer.
|
||||
*/
|
||||
*data = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
p = (char *)pointer + stat->stat_offset;
|
||||
switch (stat->sizeof_stat) {
|
||||
case sizeof(u64):
|
||||
*data = *((u64 *)p);
|
||||
break;
|
||||
case sizeof(u32):
|
||||
*data = *((u32 *)p);
|
||||
break;
|
||||
case sizeof(u16):
|
||||
*data = *((u16 *)p);
|
||||
break;
|
||||
case sizeof(u8):
|
||||
*data = *((u8 *)p);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "unexpected stat size for %s",
|
||||
stat->stat_string);
|
||||
*data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer
|
||||
* @data: ethtool stats buffer
|
||||
* @pointer: location to copy stats from
|
||||
* @stats: array of stats to copy
|
||||
* @size: the size of the stats definition
|
||||
*
|
||||
* Copy the stats defined by the stats array using the pointer as a base into
|
||||
* the data buffer supplied by ethtool. Updates the data pointer to point to
|
||||
* the next empty location for successive calls to __i40e_add_ethtool_stats.
|
||||
* If pointer is null, set the data values to zero and update the pointer to
|
||||
* skip these stats.
|
||||
**/
|
||||
static inline void
|
||||
__i40e_add_ethtool_stats(u64 **data, void *pointer,
|
||||
const struct i40e_stats stats[],
|
||||
const unsigned int size)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
i40e_add_one_ethtool_stat((*data)++, pointer, &stats[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_add_ethtool_stats - copy stats into ethtool supplied buffer
|
||||
* @data: ethtool stats buffer
|
||||
* @pointer: location where stats are stored
|
||||
* @stats: static const array of stat definitions
|
||||
*
|
||||
* Macro to ease the use of __i40e_add_ethtool_stats by taking a static
|
||||
* constant stats array and passing the ARRAY_SIZE(). This avoids typos by
|
||||
* ensuring that we pass the size associated with the given stats array.
|
||||
*
|
||||
* The parameter @stats is evaluated twice, so parameters with side effects
|
||||
* should be avoided.
|
||||
**/
|
||||
#define i40e_add_ethtool_stats(data, pointer, stats) \
|
||||
__i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))
|
||||
|
||||
/**
|
||||
* i40e_add_queue_stats - copy queue statistics into supplied buffer
|
||||
* @data: ethtool stats buffer
|
||||
* @ring: the ring to copy
|
||||
*
|
||||
* Queue statistics must be copied while protected by
|
||||
* u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats.
|
||||
* Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the
|
||||
* ring pointer is null, zero out the queue stat values and update the data
|
||||
* pointer. Otherwise safely copy the stats from the ring into the supplied
|
||||
* buffer and update the data pointer when finished.
|
||||
*
|
||||
* This function expects to be called while under rcu_read_lock().
|
||||
**/
|
||||
static inline void
|
||||
i40e_add_queue_stats(u64 **data, struct i40e_ring *ring)
|
||||
{
|
||||
const unsigned int size = ARRAY_SIZE(i40e_gstrings_queue_stats);
|
||||
const struct i40e_stats *stats = i40e_gstrings_queue_stats;
|
||||
unsigned int start;
|
||||
unsigned int i;
|
||||
|
||||
/* To avoid invalid statistics values, ensure that we keep retrying
|
||||
* the copy until we get a consistent value according to
|
||||
* u64_stats_fetch_retry_irq. But first, make sure our ring is
|
||||
* non-null before attempting to access its syncp.
|
||||
*/
|
||||
do {
|
||||
start = !ring ? 0 : u64_stats_fetch_begin_irq(&ring->syncp);
|
||||
for (i = 0; i < size; i++) {
|
||||
i40e_add_one_ethtool_stat(&(*data)[i], ring,
|
||||
&stats[i]);
|
||||
}
|
||||
} while (ring && u64_stats_fetch_retry_irq(&ring->syncp, start));
|
||||
|
||||
/* Once we successfully copy the stats in, update the data pointer */
|
||||
*data += size;
|
||||
}
|
||||
|
||||
/**
|
||||
* __i40e_add_stat_strings - copy stat strings into ethtool buffer
|
||||
* @p: ethtool supplied buffer
|
||||
* @stats: stat definitions array
|
||||
* @size: size of the stats array
|
||||
*
|
||||
* Format and copy the strings described by stats into the buffer pointed at
|
||||
* by p.
|
||||
**/
|
||||
static inline void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],
|
||||
const unsigned int size, ...)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, size);
|
||||
vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);
|
||||
*p += ETH_GSTRING_LEN;
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 40e_add_stat_strings - copy stat strings into ethtool buffer
|
||||
* @p: ethtool supplied buffer
|
||||
* @stats: stat definitions array
|
||||
*
|
||||
* Format and copy the strings described by the const static stats value into
|
||||
* the buffer pointed at by p.
|
||||
*
|
||||
* The parameter @stats is evaluated twice, so parameters with side effects
|
||||
* should be avoided. Additionally, stats must be an array such that
|
||||
* ARRAY_SIZE can be called on it.
|
||||
**/
|
||||
#define i40e_add_stat_strings(p, stats, ...) \
|
||||
__i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)
|
Loading…
Reference in New Issue
Block a user