diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/dpdk/device/dpdk.h | 3 | ||||
-rw-r--r-- | src/plugins/dpdk/device/dpdk_priv.h | 35 | ||||
-rw-r--r-- | src/plugins/dpdk/device/init.c | 74 |
3 files changed, 51 insertions, 61 deletions
diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index a069fbe3818..2440439989f 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -131,7 +131,6 @@ typedef struct u32 interface_number_from_port_id : 1; u32 use_intel_phdr_cksum : 1; u32 int_unmaskable : 1; - vlib_simple_counter_main_t *xstats_counters; } dpdk_driver_t; dpdk_driver_t *dpdk_driver_find (const char *name, const char **desc); @@ -211,6 +210,8 @@ typedef struct struct rte_eth_stats last_stats; struct rte_eth_xstat *xstats; f64 time_last_stats_update; + vlib_simple_counter_main_t xstats_counters; + u32 *xstats_symlinks; /* mac address */ u8 *default_mac_address; diff --git a/src/plugins/dpdk/device/dpdk_priv.h b/src/plugins/dpdk/device/dpdk_priv.h index e5b5a35df80..794953da55e 100644 --- a/src/plugins/dpdk/device/dpdk_priv.h +++ b/src/plugins/dpdk/device/dpdk_priv.h @@ -54,39 +54,28 @@ dpdk_get_xstats (dpdk_device_t *xd, u32 thread_index) { int ret; int i; - int len; if (!(xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)) return; - if (xd->driver == 0) - return; - len = rte_eth_xstats_get (xd->port_id, NULL, 0); - if (len < 0) - return; - - vec_validate (xd->xstats, len - 1); - ret = rte_eth_xstats_get (xd->port_id, xd->xstats, len); - if (ret < 0 || ret > len) + ret = rte_eth_xstats_get (xd->port_id, xd->xstats, vec_len (xd->xstats)); + if (ret < 0) { - /* Failed, expand vector and try again on next time around the track. */ - vec_validate (xd->xstats, ret - 1); - vec_set_len (xd->xstats, 0); dpdk_log_warn ("rte_eth_xstats_get(%d) failed: %d", xd->port_id, ret); return; } - if (len == vec_len (xd->driver->xstats_counters)) + else if (ret != vec_len (xd->xstats)) { - vec_foreach_index (i, xd->xstats) - { - vlib_set_simple_counter (&xd->driver->xstats_counters[i], - thread_index, xd->sw_if_index, - xd->xstats[i].value); - } + dpdk_log_warn ( + "rte_eth_xstats_get(%d) returned %d/%d stats. Resetting counters.", + xd->port_id, ret, vec_len (xd->xstats)); + dpdk_counters_xstats_init (xd); + return; } - else + + vec_foreach_index (i, xd->xstats) { - dpdk_log_warn ("rte_eth_xstats_get vector size mismatch (%d/%d", len, - vec_len (xd->driver->xstats_counters)); + vlib_set_simple_counter (&xd->xstats_counters, thread_index, i, + xd->xstats[i].value); } } diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index fa1b234874d..e63a281a175 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -227,71 +227,71 @@ dpdk_find_startup_config (struct rte_eth_dev_info *di) } /* - * Initialise or refresh the xstats counters for a device + * Initialise the xstats counters for a device */ void dpdk_counters_xstats_init (dpdk_device_t *xd) { int len, ret, i; struct rte_eth_xstat_name *xstats_names = 0; - char *name; - dpdk_driver_t *dr = xd->driver; - /* Only support xstats for supported drivers */ - if (!dr) - return; + if (vec_len (xd->xstats_symlinks) > 0) + { + /* xstats already initialized. Reset counters */ + vec_foreach_index (i, xd->xstats_symlinks) + { + vlib_stats_remove_entry (xd->xstats_symlinks[i]); + } + } + else + { + xd->xstats_counters.stat_segment_name = + (char *) format (0, "/if/xstats/%d%c", xd->sw_if_index, 0); + xd->xstats_counters.counters = 0; + } len = rte_eth_xstats_get_names (xd->port_id, 0, 0); if (len < 0) { - dpdk_log_err ("[%u] rte_eth_xstats_get_names failed: %d", xd->port_id, - len); - return; - } - /* Counters for this driver is already initialised */ - if (vec_len (dr->xstats_counters) == len) - { - vec_foreach_index (i, dr->xstats_counters) - { - vlib_validate_simple_counter (&dr->xstats_counters[i], - xd->sw_if_index); - vlib_zero_simple_counter (&dr->xstats_counters[i], xd->sw_if_index); - } + dpdk_log_err ("[%u] rte_eth_xstats_get_names failed: %d. DPDK xstats " + "not configured.", + xd->port_id, len); return; } - /* Same driver, different interface, different length of counter array. */ - ASSERT (vec_len (dr->xstats_counters) == 0); + vlib_validate_simple_counter (&xd->xstats_counters, len); + vlib_zero_simple_counter (&xd->xstats_counters, len); vec_validate (xstats_names, len - 1); + vec_validate (xd->xstats, len - 1); + vec_validate (xd->xstats_symlinks, len - 1); ret = rte_eth_xstats_get_names (xd->port_id, xstats_names, len); if (ret >= 0 && ret <= len) { - vec_validate (dr->xstats_counters, len - 1); vec_foreach_index (i, xstats_names) { - name = (char *) format (0, "/if/%s/%s%c", dr->drivers->name, - xstats_names[i].name, 0); - /* There is a bug in the ENA driver where the xstats names are not * unique. */ - if (vlib_stats_find_entry_index (name) != STAT_SEGMENT_INDEX_INVALID) + xd->xstats_symlinks[i] = vlib_stats_add_symlink ( + xd->xstats_counters.stats_entry_index, i, "/interfaces/%U/%s%c", + format_vnet_sw_if_index_name, vnet_get_main (), xd->sw_if_index, + xstats_names[i].name, 0); + if (xd->xstats_symlinks[i] == STAT_SEGMENT_INDEX_INVALID) { - vec_free (name); - name = (char *) format (0, "/if/%s/%s_%d%c", dr->drivers->name, - xstats_names[i].name, i, 0); + xd->xstats_symlinks[i] = vlib_stats_add_symlink ( + xd->xstats_counters.stats_entry_index, i, + "/interfaces/%U/%s_%d%c", format_vnet_sw_if_index_name, + vnet_get_main (), xd->sw_if_index, xstats_names[i].name, i, 0); } - - dr->xstats_counters[i].name = name; - dr->xstats_counters[i].stat_segment_name = name; - dr->xstats_counters[i].counters = 0; - vlib_validate_simple_counter (&dr->xstats_counters[i], - xd->sw_if_index); - vlib_zero_simple_counter (&dr->xstats_counters[i], xd->sw_if_index); - vec_free (name); } } + else + { + dpdk_log_err ("[%u] rte_eth_xstats_get_names failed: %d. DPDK xstats " + "not configured.", + xd->port_id, ret); + } vec_free (xstats_names); } |