Skip to contentSkip to conversation

eal_lcore: check /sys/devices/system/node/nodeY/cpuX as a, fallback for socket id detecting

PATCH New Wang Sheng-Hui 1 participant 1 message Apr 16, 2014

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 eal_lcore: check /sys/devices/system/node/nodeY/cpuX as a, fallback for socket id detecting

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

---
 lib/librte_eal/linuxapp/eal/eal_lcore.c | 76 +++++++++++++++++++++++++--------
 1 file changed, 59 insertions(+), 17 deletions(-)
lib/librte_eal/linuxapp/eal/eal_lcore.c +59 -17
index da20fa3..ace5cec 100644
@@ -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;
 }
 
Signature · 1 line
1.8.3.2