Add cpu_to_nid function which we can use to get the NUMA node id
by the cpu id.
1.) For live mode: use /sys/ files to get the cpu_to_nid.
This method will succeed 100%.
2.) For vmcore mode: use "numa_node" symbol to get the cpu_to_nid.
If CONFIG_USE_PERCPU_NUMA_NODE_ID does not defined in kernel,
this method will fail.
Signed-off-by: Huang Shijie <huangsj(a)hygon.cn>
---
defs.h | 2 ++
kernel.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
main.c | 1 +
3 files changed, 69 insertions(+)
diff --git a/defs.h b/defs.h
index e3027e2..7e1515a 100644
--- a/defs.h
+++ b/defs.h
@@ -6044,6 +6044,8 @@ ulong do_maple_tree(ulong, int, struct list_pair *);
void help_init(void);
void cmd_usage(char *, int);
void display_version(void);
+int cpu_to_nid(int cpu);
+void numa_init(void);
void display_help_screen(char *);
#ifdef ARM
#define dump_machdep_table(X) arm_dump_machdep_table(X)
diff --git a/kernel.c b/kernel.c
index e53038d..32230fb 100644
--- a/kernel.c
+++ b/kernel.c
@@ -12221,3 +12221,69 @@ out:
pc->error_fp = error_fp_save;
}
#endif
+
+static int *cpu_to_nid_map;
+
+int
+cpu_to_nid(int cpu)
+{
+ if (!cpu_to_nid_map || cpu < 0 || cpu >= kt->cpus)
+ return -1;
+ if (vt->numnodes == 1)
+ return 0;
+ return cpu_to_nid_map[cpu];
+}
+
+static void
+cpu_to_nid_init(void)
+{
+ int i, j;
+ int fd;
+ char buf[64];
+
+ cpu_to_nid_map = malloc(kt->cpus * sizeof(int));
+ if (vt->numnodes == 1)
+ return;
+
+ memset(cpu_to_nid_map, -1, kt->cpus * sizeof(int));
+
+ if (ACTIVE()) {
+ for (i = 0; i < kt->cpus; i++) {
+ for (j = 0; j < vt->numnodes; j++) {
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "/sys/devices/system/cpu/cpu%d/node%d", i, j);
+
+ fd = open(buf, O_RDONLY);
+ if (fd > 0) {
+ cpu_to_nid_map[i] = j;
+ close(fd);
+ break;
+ }
+ }
+ }
+ } else {
+ int cpu;
+
+ if (symbol_exists("numa_node")) {
+ ulong base = symbol_value("numa_node");
+
+ for (cpu = 0; cpu < kt->cpus; cpu++) {
+ ulong addr = base + kt->__per_cpu_offset[cpu];
+ int nid;
+
+ if (readmem(addr, KVADDR, &nid, sizeof(int),
+ "numa_node", RETURN_ON_ERROR|QUIET))
+ cpu_to_nid_map[cpu] = nid;
+ }
+ } else {
+ error(WARNING,
+ "numa_node symbol not found in vmcore\n");
+ }
+ }
+}
+
+void
+numa_init(void)
+{
+ cpu_to_nid_init();
+}
diff --git a/main.c b/main.c
index d5f8486..a8c77f8 100644
--- a/main.c
+++ b/main.c
@@ -793,6 +793,7 @@ main_loop(void)
kernel_init();
machdep_init(POST_GDB);
vm_init();
+ numa_init();
machdep_init(POST_VM);
module_init();
help_init();
--
2.53.0