Populate the platform info structure with details of all the cores on the system.
Signed-off-by: Bruce Richardson <[email protected]> --- lib/eal/common/eal_common_lcore.c | 19 +++++++++++++++++++ lib/eal/common/eal_internal_cfg.h | 16 ++++++++++++++-- lib/eal/common/eal_private.h | 8 ++++++++ lib/eal/freebsd/eal_lcore.c | 16 +++++++++++----- lib/eal/linux/eal_lcore.c | 13 +++++++++++++ lib/eal/windows/eal_lcore.c | 6 ++++++ 6 files changed, 71 insertions(+), 7 deletions(-) diff --git a/lib/eal/common/eal_common_lcore.c b/lib/eal/common/eal_common_lcore.c index 39411f9370..d8cc5e1a91 100644 --- a/lib/eal/common/eal_common_lcore.c +++ b/lib/eal/common/eal_common_lcore.c @@ -152,6 +152,7 @@ rte_eal_cpu_init(void) { /* pointer to global configuration */ struct rte_config *config = rte_eal_get_configuration(); + struct eal_platform_info *platform_info = eal_get_platform_info(); unsigned lcore_id; unsigned count = 0; unsigned int socket_id, prev_socket_id; @@ -161,6 +162,24 @@ rte_eal_cpu_init(void) int lcore_to_socket_id[RTE_MAX_LCORE] = {0}; #endif + /* allocate cpu_info for all CPUs visible to the OS */ + platform_info->cpu_count = eal_cpu_max(); + platform_info->cpu_info = calloc(platform_info->cpu_count, + sizeof(*platform_info->cpu_info)); + if (platform_info->cpu_info == NULL) { + EAL_LOG(ERR, "Cannot allocate cpu_info array"); + return -1; + } + + /* populate cpu_info with hardware topology for all detected CPUs */ + for (size_t cpu_id = 0; cpu_id < platform_info->cpu_count; cpu_id++) { + if (eal_cpu_detected(cpu_id) == 0) + continue; + platform_info->cpu_info[cpu_id].detected = true; + platform_info->cpu_info[cpu_id].numa_id = eal_cpu_socket_id(cpu_id); + platform_info->cpu_info[cpu_id].core_id = eal_cpu_core_id(cpu_id); + } + /* * Parse the maximum set of logical cores, detect the subset of running * ones and enable them by default. diff --git a/lib/eal/common/eal_internal_cfg.h b/lib/eal/common/eal_internal_cfg.h index 9a898e676e..8ed7171bdc 100644 --- a/lib/eal/common/eal_internal_cfg.h +++ b/lib/eal/common/eal_internal_cfg.h @@ -88,10 +88,22 @@ struct eal_user_cfg { }; /** - * Discovered information about cores, memory, etc. on the system. - * Immutable after initialization, so no need for atomic types or locks. + * Hardware facts about a single physical CPU, populated during CPU discovery. + * Indexed by physical CPU ID (not DPDK lcore ID). + */ +struct eal_cpu_info { + bool detected; /**< true if this CPU ID is valid and visible to the OS */ + unsigned int numa_id; /**< NUMA node this CPU belongs to */ + unsigned int core_id; /**< physical core number on its NUMA node */ +}; + +/** + * Discovered information about the system hardware. + * Immutable after discovery. */ struct eal_platform_info { + size_t cpu_count; /**< number of entries in cpu_info[] */ + struct eal_cpu_info *cpu_info; /**< per-physical-CPU hardware facts */ uint8_t num_hugepage_sizes; /**< how many sizes on this system */ struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES]; }; diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h index d9807fb2fb..00a73a9d61 100644 --- a/lib/eal/common/eal_private.h +++ b/lib/eal/common/eal_private.h @@ -388,6 +388,14 @@ unsigned eal_cpu_core_id(unsigned lcore_id); */ int eal_cpu_detected(unsigned lcore_id); +/** + * Get the number of CPU IDs to allocate for platform CPU info. + * Returns max_cpu_id + 1: all valid CPU IDs are in [0, eal_cpu_max()). + * + * This function is private to the EAL. + */ +size_t eal_cpu_max(void); + /** * Set TSC frequency from precise value or estimation * diff --git a/lib/eal/freebsd/eal_lcore.c b/lib/eal/freebsd/eal_lcore.c index 1d3d1b67b9..c20d25358b 100644 --- a/lib/eal/freebsd/eal_lcore.c +++ b/lib/eal/freebsd/eal_lcore.c @@ -2,7 +2,10 @@ * Copyright(c) 2010-2014 Intel Corporation */ +#include <sched.h> +#include <errno.h> #include <unistd.h> +#include <string.h> #include <sys/sysctl.h> #include <rte_log.h> @@ -21,18 +24,21 @@ eal_cpu_core_id(__rte_unused unsigned lcore_id) return 0; } -static int -eal_get_ncpus(void) +size_t +eal_cpu_max(void) { static int ncpu = -1; int mib[2] = {CTL_HW, HW_NCPU}; size_t len = sizeof(ncpu); if (ncpu < 0) { - sysctl(mib, 2, &ncpu, &len, NULL, 0); + if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) { + EAL_LOG(ERR, "sysctl failed to get number of CPUs: %s", strerror(errno)); + return CPU_SETSIZE; /* fallback to CPU_SETSIZE */ + } EAL_LOG(INFO, "Sysctl reports %d cpus", ncpu); } - return ncpu; + return (size_t)ncpu; } unsigned @@ -47,6 +53,6 @@ eal_cpu_socket_id(__rte_unused unsigned cpu_id) int eal_cpu_detected(unsigned lcore_id) { - const unsigned ncpus = eal_get_ncpus(); + const unsigned ncpus = eal_cpu_max(); return lcore_id < ncpus; } diff --git a/lib/eal/linux/eal_lcore.c b/lib/eal/linux/eal_lcore.c index 29b36dd610..6a806336bd 100644 --- a/lib/eal/linux/eal_lcore.c +++ b/lib/eal/linux/eal_lcore.c @@ -72,3 +72,16 @@ eal_cpu_core_id(unsigned lcore_id) "for lcore %u - assuming core 0", SYS_CPU_DIR, lcore_id); return 0; } + +size_t +eal_cpu_max(void) +{ + long n = sysconf(_SC_NPROCESSORS_CONF); + + if (n <= 0) { + EAL_LOG(WARNING, "sysconf(_SC_NPROCESSORS_CONF) failed, " + "falling back to CPU_SETSIZE"); + return CPU_SETSIZE; + } + return (size_t)n; +} diff --git a/lib/eal/windows/eal_lcore.c b/lib/eal/windows/eal_lcore.c index a498044620..dcbba383f7 100644 --- a/lib/eal/windows/eal_lcore.c +++ b/lib/eal/windows/eal_lcore.c @@ -239,6 +239,12 @@ eal_cpu_core_id(unsigned int lcore_id) return cpu_map.lcores[lcore_id].core_id; } +size_t +eal_cpu_max(void) +{ + return (size_t)cpu_map.lcore_count; +} + unsigned int eal_socket_numa_node(unsigned int socket_id) { -- 2.51.0

