3 ways to get the NUMA info: 1) check the existence of symlink /sys/devices/system/cpu/cpuX/nodeY 2) check the existence of symlink /sys/devices/system/node/nodeY/cpuX 3) get the value from /sys/devices/system/cpu/cpuX/topology/physical_package_id
Signed-off-by: Wang Sheng-Hui <shhuiw at gmail.com> --- lib/librte_eal/linuxapp/eal/eal_lcore.c | 76 +++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 17 deletions(-) diff --git a/lib/librte_eal/linuxapp/eal/eal_lcore.c b/lib/librte_eal/linuxapp/eal/eal_lcore.c index da20fa3..ace5cec 100644 --- a/lib/librte_eal/linuxapp/eal/eal_lcore.c +++ b/lib/librte_eal/linuxapp/eal/eal_lcore.c @@ -35,6 +35,9 @@ #include <limits.h> #include <string.h> #include <dirent.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include <rte_log.h> #include <rte_eal.h> @@ -49,6 +52,7 @@ #define SYS_CPU_DIR "/sys/devices/system/cpu/cpu%u" #define CORE_ID_FILE "topology/core_id" #define PHYS_PKG_FILE "topology/physical_package_id" +#define SYS_NODE_DIR "/sys/devices/system/node" /* Check if a cpu is present by the presence of the cpu information for it */ static int @@ -66,31 +70,36 @@ cpu_detected(unsigned lcore_id) } /* Get CPU socket id (NUMA node) by reading directory - * /sys/devices/system/cpu/cpuX looking for symlink "nodeY" + * /sys/devices/system/cpu/cpuX looking for symlink "nodeY", + * or /sys/devices/system/node/nodeY for symlink "cpuX", * which gives the NUMA topology information. * Note: physical package id != NUMA node, but we use it as a - * fallback for kernels which don't create a nodeY link + * fallback for kernels which don't create a nodeY or cpuX link. */ static unsigned cpu_socket_id(unsigned lcore_id) { const char node_prefix[] = "node"; + const char cpu_prefix[] = "cpu"; const size_t prefix_len = sizeof(node_prefix) - 1; char path[PATH_MAX]; DIR *d; + DIR *sub_dir = NULL; unsigned long id = 0; struct dirent *e; char *endptr = NULL; + RTE_LOG(DEBUG, EAL, "Read numa node link for lcore %u from" + "/sys/devices/system/cpu/cpu%u/nodeX\n", + lcore_id, lcore_id); + int len = rte_snprintf(path, sizeof(path), SYS_CPU_DIR, lcore_id); if (len <= 0 || (unsigned)len >= sizeof(path)) goto err; - d = opendir(path); if (!d) goto err; - while ((e = readdir(d)) != NULL) { if (strncmp(e->d_name, node_prefix, prefix_len) == 0) { id = strtoul(e->d_name+prefix_len, &endptr, 0); @@ -98,23 +107,56 @@ cpu_socket_id(unsigned lcore_id) } } closedir(d); - if (endptr == NULL || *endptr!='\0' || endptr == e->d_name+prefix_len) { - RTE_LOG(WARNING, EAL, "Cannot read numa node link " - "for lcore %u - using physical package id instead\n", - lcore_id); - - len = rte_snprintf(path, sizeof(path), SYS_CPU_DIR "/%s", - lcore_id, PHYS_PKG_FILE); - if (len <= 0 || (unsigned)len >= sizeof(path)) - goto err; - if (eal_parse_sysfs_value(path, &id) != 0) - goto err; + if (! (endptr == NULL || *endptr!='\0' || + endptr == e->d_name+prefix_len)) + goto out; + + RTE_LOG(DEBUG, EAL, "Read numa node topo for lcore %u from " + "/sys/devices/system/node/nodeX/cpu%u\n", + lcore_id, lcore_id); + + len = rte_snprintf(path, sizeof(path), SYS_NODE_DIR); + if (len <= 0 || (unsigned)len >= sizeof(path)) + goto err; + d = opendir(path); + if (!d) + goto err; + while ((e = readdir(d)) != NULL) { + if (strncmp(e->d_name, node_prefix, prefix_len) == 0) { + len = rte_snprintf(path, sizeof(path), SYS_NODE_DIR "/%s/%s%d", + e->d_name, cpu_prefix, lcore_id); + if (len <= 0 || (unsigned)len >= sizeof(path)) + goto err; + sub_dir = opendir(path); + closedir(sub_dir); + if (!sub_dir) + continue; + id = strtoul(e->d_name+prefix_len, &endptr, 0); + break; + } } + closedir(d); + if (! (endptr == NULL || *endptr!='\0' || + endptr == e->d_name+prefix_len)) + goto out; + + RTE_LOG(WARNING, EAL, "Cannot read numa node link " + "for lcore %u - using physical package id instead\n", + lcore_id); + len = rte_snprintf(path, sizeof(path), SYS_CPU_DIR "/%s", + lcore_id, PHYS_PKG_FILE); + if (len <= 0 || (unsigned)len >= sizeof(path)) + goto err; + if (eal_parse_sysfs_value(path, &id) != 0) + goto err; + +out: return (unsigned)id; err: - RTE_LOG(ERR, EAL, "Error getting NUMA socket information from %s " - "for lcore %u - assuming NUMA socket 0\n", SYS_CPU_DIR, lcore_id); + RTE_LOG(ERR, EAL, "Error getting NUMA socket information from %s or %s" + "for lcore %u - assuming NUMA socket 0\n", SYS_CPU_DIR, + SYS_NODE_DIR, lcore_id); return 0; } -- 1.8.3.2