@@ -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;
}