aboutsummaryrefslogtreecommitdiffstats
path: root/vnet/vnet/devices/dpdk/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'vnet/vnet/devices/dpdk/device.c')
-rw-r--r--vnet/vnet/devices/dpdk/device.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/vnet/vnet/devices/dpdk/device.c b/vnet/vnet/devices/dpdk/device.c
index 748fb829115..7821ebeb7c2 100644
--- a/vnet/vnet/devices/dpdk/device.c
+++ b/vnet/vnet/devices/dpdk/device.c
@@ -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);
+}