i40e: convert VEB TC stats to use an i40e_stats array
The VEB TC stats are currently implemented with separate parsing, instead of using the i40e_stats array and associated helper functions. This is likely because the stats rely on embedding the TC number into the stat name. Update i40e_add_stat_strings to take variadic arguments, and use these to vsnprintf the i40e_stats string as a string containing format specifiers. Create a stats array for the VEB TC related stats, i40e_gstrings_veb_tc_stats, and use this along with the helper functions to remove the specialized boiler plate code. Always call i40e_add_ethtool_stats for both this array and the general VEB stats array. This ensures that we zero out any memory in case it was not zero-allocated for us. This ultimately results in less boiler plate code for the i40e_get_stat_strings and i40e_get_ethtool_stats. 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
1ac2ee231f
commit
1510ae0be2
@ -7,6 +7,11 @@
|
|||||||
#include "i40e_diag.h"
|
#include "i40e_diag.h"
|
||||||
|
|
||||||
struct i40e_stats {
|
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];
|
char stat_string[ETH_GSTRING_LEN];
|
||||||
int sizeof_stat;
|
int sizeof_stat;
|
||||||
int stat_offset;
|
int stat_offset;
|
||||||
@ -56,6 +61,13 @@ static const struct i40e_stats i40e_gstrings_veb_stats[] = {
|
|||||||
I40E_VEB_STAT("veb.rx_unknown_protocol", stats.rx_unknown_protocol),
|
I40E_VEB_STAT("veb.rx_unknown_protocol", stats.rx_unknown_protocol),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct i40e_stats i40e_gstrings_veb_tc_stats[] = {
|
||||||
|
I40E_VEB_STAT("veb.tc_%u_tx_packets", tc_stats.tc_tx_packets),
|
||||||
|
I40E_VEB_STAT("veb.tc_%u_tx_bytes", tc_stats.tc_tx_bytes),
|
||||||
|
I40E_VEB_STAT("veb.tc_%u_rx_packets", tc_stats.tc_rx_packets),
|
||||||
|
I40E_VEB_STAT("veb.tc_%u_rx_bytes", tc_stats.tc_rx_bytes),
|
||||||
|
};
|
||||||
|
|
||||||
static const struct i40e_stats i40e_gstrings_misc_stats[] = {
|
static const struct i40e_stats i40e_gstrings_misc_stats[] = {
|
||||||
I40E_VSI_STAT("rx_unicast", eth_stats.rx_unicast),
|
I40E_VSI_STAT("rx_unicast", eth_stats.rx_unicast),
|
||||||
I40E_VSI_STAT("tx_unicast", eth_stats.tx_unicast),
|
I40E_VSI_STAT("tx_unicast", eth_stats.tx_unicast),
|
||||||
@ -162,16 +174,14 @@ static const struct i40e_stats i40e_gstrings_stats[] = {
|
|||||||
FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_tx) + \
|
FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_tx) + \
|
||||||
FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_2_xoff)) \
|
FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_2_xoff)) \
|
||||||
/ sizeof(u64))
|
/ sizeof(u64))
|
||||||
#define I40E_VEB_TC_STATS_LEN ( \
|
|
||||||
(FIELD_SIZEOF(struct i40e_veb, tc_stats.tc_rx_packets) + \
|
#define I40E_VEB_STATS_LEN (ARRAY_SIZE(i40e_gstrings_veb_stats) + \
|
||||||
FIELD_SIZEOF(struct i40e_veb, tc_stats.tc_rx_bytes) + \
|
(ARRAY_SIZE(i40e_gstrings_veb_tc_stats) * \
|
||||||
FIELD_SIZEOF(struct i40e_veb, tc_stats.tc_tx_packets) + \
|
I40E_MAX_TRAFFIC_CLASS))
|
||||||
FIELD_SIZEOF(struct i40e_veb, tc_stats.tc_tx_bytes)) \
|
|
||||||
/ sizeof(u64))
|
|
||||||
#define I40E_VEB_STATS_LEN ARRAY_SIZE(i40e_gstrings_veb_stats)
|
|
||||||
#define I40E_VEB_STATS_TOTAL (I40E_VEB_STATS_LEN + I40E_VEB_TC_STATS_LEN)
|
|
||||||
#define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \
|
#define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \
|
||||||
I40E_PFC_STATS_LEN + \
|
I40E_PFC_STATS_LEN + \
|
||||||
|
I40E_VEB_STATS_LEN + \
|
||||||
I40E_VSI_STATS_LEN((n)))
|
I40E_VSI_STATS_LEN((n)))
|
||||||
|
|
||||||
enum i40e_ethtool_test_id {
|
enum i40e_ethtool_test_id {
|
||||||
@ -1681,7 +1691,7 @@ static int i40e_get_stats_count(struct net_device *netdev)
|
|||||||
struct i40e_pf *pf = vsi->back;
|
struct i40e_pf *pf = vsi->back;
|
||||||
|
|
||||||
if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1)
|
if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1)
|
||||||
return I40E_PF_STATS_LEN(netdev) + I40E_VEB_STATS_TOTAL;
|
return I40E_PF_STATS_LEN(netdev);
|
||||||
else
|
else
|
||||||
return I40E_VSI_STATS_LEN(netdev);
|
return I40E_VSI_STATS_LEN(netdev);
|
||||||
}
|
}
|
||||||
@ -1809,8 +1819,10 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
|
|||||||
struct i40e_ring *tx_ring, *rx_ring;
|
struct i40e_ring *tx_ring, *rx_ring;
|
||||||
struct i40e_vsi *vsi = np->vsi;
|
struct i40e_vsi *vsi = np->vsi;
|
||||||
struct i40e_pf *pf = vsi->back;
|
struct i40e_pf *pf = vsi->back;
|
||||||
|
struct i40e_veb *veb = pf->veb[pf->lan_veb];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int start;
|
unsigned int start;
|
||||||
|
bool veb_stats;
|
||||||
|
|
||||||
i40e_update_stats(vsi);
|
i40e_update_stats(vsi);
|
||||||
|
|
||||||
@ -1855,21 +1867,19 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
|
|||||||
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
|
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((pf->lan_veb != I40E_NO_VEB) &&
|
veb_stats = ((pf->lan_veb != I40E_NO_VEB) &&
|
||||||
(pf->flags & I40E_FLAG_VEB_STATS_ENABLED)) {
|
(pf->flags & I40E_FLAG_VEB_STATS_ENABLED));
|
||||||
struct i40e_veb *veb = pf->veb[pf->lan_veb];
|
|
||||||
|
|
||||||
i40e_add_ethtool_stats(&data, veb, i40e_gstrings_veb_stats);
|
/* If veb stats aren't enabled, pass NULL instead of the veb so that
|
||||||
|
* we initialize stats to zero and update the data pointer
|
||||||
|
* intelligently
|
||||||
|
*/
|
||||||
|
i40e_add_ethtool_stats(&data, veb_stats ? veb : NULL,
|
||||||
|
i40e_gstrings_veb_stats);
|
||||||
|
|
||||||
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
|
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
|
||||||
*(data++) = veb->tc_stats.tc_tx_packets[i];
|
i40e_add_ethtool_stats(&data, veb_stats ? veb : NULL,
|
||||||
*(data++) = veb->tc_stats.tc_tx_bytes[i];
|
i40e_gstrings_veb_tc_stats);
|
||||||
*(data++) = veb->tc_stats.tc_rx_packets[i];
|
|
||||||
*(data++) = veb->tc_stats.tc_rx_bytes[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data += I40E_VEB_STATS_TOTAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
i40e_add_ethtool_stats(&data, pf, i40e_gstrings_stats);
|
i40e_add_ethtool_stats(&data, pf, i40e_gstrings_stats);
|
||||||
|
|
||||||
@ -1891,16 +1901,21 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
|
|||||||
* @stats: stat definitions array
|
* @stats: stat definitions array
|
||||||
* @size: size of the stats array
|
* @size: size of the stats array
|
||||||
*
|
*
|
||||||
* Copy the strings described by stats into the buffer pointed at by p.
|
* 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[],
|
static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],
|
||||||
const unsigned int size)
|
const unsigned int size, ...)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
snprintf(*p, ETH_GSTRING_LEN, "%s", stats[i].stat_string);
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, size);
|
||||||
|
vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);
|
||||||
*p += ETH_GSTRING_LEN;
|
*p += ETH_GSTRING_LEN;
|
||||||
|
va_end(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1914,7 +1929,7 @@ static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],
|
|||||||
* for it.
|
* for it.
|
||||||
**/
|
**/
|
||||||
#define i40e_add_stat_strings(p, stats, ...) \
|
#define i40e_add_stat_strings(p, stats, ...) \
|
||||||
__i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats))
|
__i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i40e_get_stat_strings - copy stat strings into supplied buffer
|
* i40e_get_stat_strings - copy stat strings into supplied buffer
|
||||||
@ -1953,20 +1968,8 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
|
|||||||
|
|
||||||
i40e_add_stat_strings(&data, i40e_gstrings_veb_stats);
|
i40e_add_stat_strings(&data, i40e_gstrings_veb_stats);
|
||||||
|
|
||||||
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
|
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
|
||||||
snprintf(data, ETH_GSTRING_LEN,
|
i40e_add_stat_strings(&data, i40e_gstrings_veb_tc_stats, i);
|
||||||
"veb.tc_%u_tx_packets", i);
|
|
||||||
data += ETH_GSTRING_LEN;
|
|
||||||
snprintf(data, ETH_GSTRING_LEN,
|
|
||||||
"veb.tc_%u_tx_bytes", i);
|
|
||||||
data += ETH_GSTRING_LEN;
|
|
||||||
snprintf(data, ETH_GSTRING_LEN,
|
|
||||||
"veb.tc_%u_rx_packets", i);
|
|
||||||
data += ETH_GSTRING_LEN;
|
|
||||||
snprintf(data, ETH_GSTRING_LEN,
|
|
||||||
"veb.tc_%u_rx_bytes", i);
|
|
||||||
data += ETH_GSTRING_LEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
i40e_add_stat_strings(&data, i40e_gstrings_stats);
|
i40e_add_stat_strings(&data, i40e_gstrings_stats);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user