[dpdk-dev] eal_lcore: check /sys/devices/system/node/nodeY/cpuX as a, fallback for socket id detecting

Message ID 534DD019.108@gmail.com
State Not Applicable, archived
Headers show

Commit Message

Wang Sheng-Hui April 16, 2014, 12:34 a.m. UTC
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@gmail.com>
---
 lib/librte_eal/linuxapp/eal/eal_lcore.c | 76 +++++++++++++++++++++++++--------
 1 file changed, 59 insertions(+), 17 deletions(-)

Patch

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