diff options
Diffstat (limited to 'src/plugins/dpdk/device/init.c')
-rw-r--r-- | src/plugins/dpdk/device/init.c | 109 |
1 files changed, 97 insertions, 12 deletions
diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index d15cfd7233a..453d9cff7ef 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -30,7 +30,7 @@ #include <dpdk/cryptodev/cryptodev.h> #include <vlib/pci/pci.h> #include <vlib/vmbus/vmbus.h> - +#include <vlib/stats/stats.h> #include <rte_ring.h> #include <rte_vect.h> @@ -187,9 +187,11 @@ dpdk_find_startup_config (struct rte_eth_dev_info *di) { dpdk_main_t *dm = &dpdk_main; struct rte_pci_device *pci_dev; - struct rte_vmbus_device *vmbus_dev; vlib_pci_addr_t pci_addr; +#ifdef __linux__ + struct rte_vmbus_device *vmbus_dev; vlib_vmbus_addr_t vmbus_addr; +#endif /* __linux__ */ uword *p = 0; if ((pci_dev = dpdk_get_pci_device (di))) @@ -202,6 +204,7 @@ dpdk_find_startup_config (struct rte_eth_dev_info *di) hash_get (dm->conf->device_config_index_by_pci_addr, pci_addr.as_u32); } +#ifdef __linux__ if ((vmbus_dev = dpdk_get_vmbus_device (di))) { unformat_input_t input_vmbus; @@ -216,12 +219,82 @@ dpdk_find_startup_config (struct rte_eth_dev_info *di) &vmbus_addr); unformat_free (&input_vmbus); } +#endif /* __linux__ */ if (p) return pool_elt_at_index (dm->conf->dev_confs, p[0]); return &dm->conf->default_devconf; } +/* + * Initialise or refresh 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; + + 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); + } + return; + } + + /* Same driver, different interface, different length of counter array. */ + ASSERT (vec_len (dr->xstats_counters) == 0); + + vec_validate (xstats_names, 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) + { + vec_free (name); + name = (char *) format (0, "/if/%s/%s_%d%c", dr->drivers->name, + 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); + } + } + vec_free (xstats_names); +} + static clib_error_t * dpdk_lib_init (dpdk_main_t * dm) { @@ -528,6 +601,7 @@ dpdk_lib_init (dpdk_main_t * dm) if (vec_len (xd->errors)) dpdk_log_err ("[%u] setup failed Errors:\n %U", port_id, format_dpdk_device_errors, xd); + dpdk_counters_xstats_init (xd); } for (int i = 0; i < vec_len (dm->devices); i++) @@ -566,8 +640,18 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf) continue; } +#ifdef __FreeBSD__ + /* + * The defines for the PCI_CLASS_* types are platform specific and differ + * on FreeBSD. + */ + if (d->device_class != PCI_CLASS_NETWORK && + d->device_class != PCI_CLASS_PROCESSOR_CO) + continue; +#else if (d->device_class != PCI_CLASS_NETWORK_ETHERNET && d->device_class != PCI_CLASS_PROCESSOR_CO) continue; +#endif /* __FreeBSD__ */ if (num_whitelisted) { @@ -1031,12 +1115,14 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) dpdk_main_t *dm = &dpdk_main; clib_error_t *error = 0; dpdk_config_main_t *conf = &dpdk_config_main; - vlib_thread_main_t *tm = vlib_get_thread_main (); dpdk_device_config_t *devconf; vlib_pci_addr_t pci_addr = { 0 }; vlib_vmbus_addr_t vmbus_addr = { 0 }; unformat_input_t sub_input; +#ifdef __linux + vlib_thread_main_t *tm = vlib_get_thread_main (); uword default_hugepage_sz, x; +#endif /* __linux__ */ u8 *s, *tmp = 0; int ret, i; int num_whitelisted = 0; @@ -1045,15 +1131,11 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) u8 no_vmbus = 0; u8 file_prefix = 0; u8 *socket_mem = 0; - u8 *huge_dir_path = 0; u32 vendor, device, domain, bus, func; void *fmt_func; void *fmt_addr; f64 poll_interval; - huge_dir_path = - format (0, "%s/hugepages%c", vlib_unix_get_runtime_dir (), 0); - conf->device_config_index_by_pci_addr = hash_create (0, sizeof (uword)); mhash_init (&conf->device_config_index_by_vmbus_addr, sizeof (uword), sizeof (vlib_vmbus_addr_t)); @@ -1248,6 +1330,11 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) { vec_add1 (conf->eal_init_args, (u8 *) "--in-memory"); +#ifdef __linux__ + /* + * FreeBSD performs huge page prealloc through a dedicated kernel mode + * this process is only required on Linux. + */ default_hugepage_sz = clib_mem_get_default_hugepage_size (); clib_bitmap_foreach (x, tm->cpu_socket_bitmap) @@ -1262,6 +1349,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) if ((e = clib_sysfs_prealloc_hugepages(x, 0, n_pages))) clib_error_report (e); } +#endif /* __linux__ */ } /* on/off dpdk's telemetry thread */ @@ -1270,6 +1358,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) vec_add1 (conf->eal_init_args, (u8 *) "--no-telemetry"); } +#ifdef __linux__ if (!file_prefix) { tmp = format (0, "--file-prefix%c", 0); @@ -1277,6 +1366,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) tmp = format (0, "vpp%c", 0); vec_add1 (conf->eal_init_args, tmp); } +#endif if (no_pci == 0 && geteuid () == 0) dpdk_bind_devices_to_uio (conf); @@ -1396,11 +1486,6 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) RTE_VECT_SIMD_256 : RTE_VECT_SIMD_512); - /* lazy umount hugepages */ - umount2 ((char *) huge_dir_path, MNT_DETACH); - rmdir ((char *) huge_dir_path); - vec_free (huge_dir_path); - /* main thread 1st */ if ((error = dpdk_buffer_pools_create (vm))) return error; |