Add API to get the dpdk interface stats delta.
Internally change the clearing and displaying of the dpdk stats to be based on deltas. Change-Id: I76605ac67492a374ff5522ff44d4a0190cf94e18 Signed-off-by: Todd Foggoa (tfoggoa) <tfoggoa@cisco.com>
This commit is contained in:
@ -835,17 +835,27 @@ static void dpdk_clear_hw_interface_counters (u32 instance)
|
||||
*/
|
||||
if (xd->admin_up != 0xff)
|
||||
{
|
||||
rte_eth_stats_reset (xd->device_index);
|
||||
memset (&xd->last_stats, 0, sizeof (xd->last_stats));
|
||||
/*
|
||||
* Set the "last_cleared_stats" to the current stats, so that
|
||||
* things appear to clear from a display perspective.
|
||||
*/
|
||||
dpdk_update_counters (xd, vlib_time_now (dm->vlib_main));
|
||||
|
||||
memcpy (&xd->last_cleared_stats, &xd->stats, sizeof(xd->stats));
|
||||
memcpy (xd->last_cleared_xstats, xd->xstats,
|
||||
vec_len(xd->last_cleared_xstats) *
|
||||
sizeof(xd->last_cleared_xstats[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
rte_eth_stats_reset (xd->device_index);
|
||||
memset(&xd->stats, 0, sizeof(xd->stats));
|
||||
/*
|
||||
* Internally rte_eth_xstats_reset() is calling rte_eth_stats_reset(),
|
||||
* so we're only calling xstats_reset() here.
|
||||
*/
|
||||
rte_eth_xstats_reset (xd->device_index);
|
||||
memset (&xd->stats, 0, sizeof(xd->stats));
|
||||
memset (&xd->last_stats, 0, sizeof (xd->last_stats));
|
||||
}
|
||||
rte_eth_xstats_reset(xd->device_index);
|
||||
|
||||
if (PREDICT_FALSE(xd->dev_type == VNET_DPDK_DEV_VHOST_USER)) {
|
||||
int i;
|
||||
@ -1225,3 +1235,27 @@ int rte_delay_us_override (unsigned us) {
|
||||
}
|
||||
return 0; // no override
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a copy of the DPDK port stats in dest.
|
||||
*/
|
||||
clib_error_t*
|
||||
dpdk_get_hw_interface_stats (u32 hw_if_index, struct rte_eth_stats* dest)
|
||||
{
|
||||
dpdk_main_t * dm = &dpdk_main;
|
||||
vnet_main_t * vnm = vnet_get_main();
|
||||
vnet_hw_interface_t * hi = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
dpdk_device_t * xd = vec_elt_at_index (dm->devices, hi->dev_instance);
|
||||
|
||||
if (!dest) {
|
||||
return clib_error_return (0, "Missing or NULL argument");
|
||||
}
|
||||
if (!xd) {
|
||||
return clib_error_return (0, "Unable to get DPDK device from HW interface");
|
||||
}
|
||||
|
||||
dpdk_update_counters (xd, vlib_time_now (dm->vlib_main));
|
||||
|
||||
memcpy(dest, &xd->stats, sizeof(xd->stats));
|
||||
return (0);
|
||||
}
|
||||
|
@ -245,7 +245,9 @@ typedef struct {
|
||||
|
||||
struct rte_eth_stats stats;
|
||||
struct rte_eth_stats last_stats;
|
||||
struct rte_eth_stats last_cleared_stats;
|
||||
struct rte_eth_xstats * xstats;
|
||||
struct rte_eth_xstats * last_cleared_xstats;
|
||||
f64 time_last_stats_update;
|
||||
dpdk_port_type_t port_type;
|
||||
|
||||
@ -567,6 +569,9 @@ u32 dpdk_get_admin_up_down_in_progress (void);
|
||||
uword
|
||||
dpdk_input_rss (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * f);
|
||||
|
||||
clib_error_t*
|
||||
dpdk_get_hw_interface_stats (u32 hw_if_index, struct rte_eth_stats* dest);
|
||||
|
||||
format_function_t format_dpdk_device_name;
|
||||
format_function_t format_dpdk_device;
|
||||
format_function_t format_dpdk_tx_dma_trace;
|
||||
|
@ -141,6 +141,27 @@ dpdk_rx_burst ( dpdk_main_t * dm, dpdk_device_t * xd, u16 queue_id)
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
dpdk_get_xstats (dpdk_device_t * xd)
|
||||
{
|
||||
int len;
|
||||
if ((len = rte_eth_xstats_get(xd->device_index, NULL, 0)) > 0)
|
||||
{
|
||||
vec_validate(xd->xstats, len - 1);
|
||||
vec_validate(xd->last_cleared_xstats, len - 1);
|
||||
|
||||
len = rte_eth_xstats_get(xd->device_index, xd->xstats, vec_len(xd->xstats));
|
||||
|
||||
ASSERT(vec_len(xd->xstats) == len);
|
||||
ASSERT(vec_len(xd->last_cleared_xstats) == len);
|
||||
|
||||
_vec_len(xd->xstats) = len;
|
||||
_vec_len(xd->last_cleared_xstats) = len;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
dpdk_update_counters (dpdk_device_t * xd, f64 now)
|
||||
{
|
||||
@ -148,7 +169,6 @@ dpdk_update_counters (dpdk_device_t * xd, f64 now)
|
||||
vnet_main_t * vnm = vnet_get_main();
|
||||
u32 my_cpu = os_get_cpu_number();
|
||||
u64 rxerrors, last_rxerrors;
|
||||
int len;
|
||||
|
||||
/* only update counters for PMD interfaces */
|
||||
if (xd->dev_type != VNET_DPDK_DEV_ETH)
|
||||
@ -207,11 +227,5 @@ dpdk_update_counters (dpdk_device_t * xd, f64 now)
|
||||
}
|
||||
}
|
||||
|
||||
if ((len = rte_eth_xstats_get(xd->device_index, NULL, 0)) > 0)
|
||||
{
|
||||
vec_validate(xd->xstats, len - 1);
|
||||
len = rte_eth_xstats_get(xd->device_index, xd->xstats, vec_len(xd->xstats));
|
||||
ASSERT(vec_len(xd->xstats) == len);
|
||||
_vec_len(xd->xstats) = len;
|
||||
}
|
||||
dpdk_get_xstats(xd);
|
||||
}
|
||||
|
@ -529,27 +529,37 @@ u8 * format_dpdk_device (u8 * s, va_list * args)
|
||||
|
||||
{
|
||||
#define _(N, V) \
|
||||
if (xd->stats.V != 0) \
|
||||
s = format (s, "\n%U%-40U%16Ld", \
|
||||
format_white_space, indent + 2, \
|
||||
format_c_identifier, #N, xd->stats.V);
|
||||
if ((xd->stats.V - xd->last_cleared_stats.V) != 0) { \
|
||||
s = format (s, "\n%U%-40U%16Ld", \
|
||||
format_white_space, indent + 2, \
|
||||
format_c_identifier, #N, \
|
||||
xd->stats.V - xd->last_cleared_stats.V); \
|
||||
} \
|
||||
|
||||
foreach_dpdk_counter
|
||||
#undef _
|
||||
}
|
||||
|
||||
u8 * xs = 0;
|
||||
struct rte_eth_xstats * xstat;
|
||||
u32 i = 0;
|
||||
|
||||
vec_foreach(xstat, xd->xstats)
|
||||
ASSERT(vec_len(xd->xstats) == vec_len(xd->last_cleared_xstats));
|
||||
|
||||
vec_foreach_index(i, xd->xstats)
|
||||
{
|
||||
if (verbose == 2 || (verbose && xstat->value))
|
||||
u64 delta = 0;
|
||||
struct rte_eth_xstats* xstat = vec_elt_at_index(xd->xstats, i);
|
||||
struct rte_eth_xstats* last_xstat =
|
||||
vec_elt_at_index(xd->last_cleared_xstats, i);
|
||||
|
||||
delta = xstat->value - last_xstat->value;
|
||||
if (verbose == 2 || (verbose && delta))
|
||||
{
|
||||
/* format_c_identifier don't like c strings inside vector */
|
||||
/* format_c_identifier doesn't like c strings inside vector */
|
||||
u8 * name = format(0,"%s", xstat->name);
|
||||
xs = format(xs, "\n%U%-38U%16Ld",
|
||||
format_white_space, indent + 4,
|
||||
format_c_identifier, name, xstat->value);
|
||||
format_c_identifier, name, delta);
|
||||
vec_free(name);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user