From 69a5c53074bc808d0b6ba49343ffd9f0efca4975 Mon Sep 17 00:00:00 2001 From: Balazs Gerofi Date: Sat, 5 Nov 2016 16:12:08 +0900 Subject: [PATCH] NUMA: hide non-existing nodes from /sys/devices/system/node listing --- executer/include/uprotocol.h | 1 + executer/kernel/mcctrl/control.c | 13 +++++++ executer/kernel/mcctrl/driver.c | 1 + executer/kernel/mcctrl/sysfs_files.c | 2 + executer/user/mcexec.c | 58 ++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+) diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index 34ad9a1a..b7e3020e 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -41,6 +41,7 @@ #define MCEXEC_UP_NEW_PROCESS 0x30a02909 #define MCEXEC_UP_GET_CRED 0x30a0290a #define MCEXEC_UP_GET_CREDV 0x30a0290b +#define MCEXEC_UP_GET_NODES 0x30a0290c #define MCEXEC_UP_PREPARE_DMA 0x30a02910 #define MCEXEC_UP_FREE_DMA 0x30a02911 diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 3cac5da6..4c07cd66 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -450,6 +450,16 @@ static long mcexec_get_cpu(ihk_os_t os) return info->n_cpus; } +static long mcexec_get_nodes(ihk_os_t os) +{ + struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); + + if (!usrdata || !usrdata->mem_info) + return -EINVAL; + + return usrdata->mem_info->n_numa_nodes; +} + int mcctrl_add_per_proc_data(struct mcctrl_usrdata *ud, int pid, struct mcctrl_per_proc_data *ppd) { @@ -1268,6 +1278,9 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg, case MCEXEC_UP_GET_CPU: return mcexec_get_cpu(os); + case MCEXEC_UP_GET_NODES: + return mcexec_get_nodes(os); + case MCEXEC_UP_STRNCPY_FROM_USER: return mcexec_strncpy_from_user(os, (struct strncpy_from_user_desc *)arg); diff --git a/executer/kernel/mcctrl/driver.c b/executer/kernel/mcctrl/driver.c index 0b2475fe..ed1a09af 100644 --- a/executer/kernel/mcctrl/driver.c +++ b/executer/kernel/mcctrl/driver.c @@ -60,6 +60,7 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = { { .request = MCEXEC_UP_LOAD_SYSCALL, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_SEND_SIGNAL, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_GET_CPU, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_GET_NODES, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_STRNCPY_FROM_USER, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_NEW_PROCESS, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_PREPARE_DMA, .func = mcctrl_ioctl }, diff --git a/executer/kernel/mcctrl/sysfs_files.c b/executer/kernel/mcctrl/sysfs_files.c index f2c29827..edc8360a 100644 --- a/executer/kernel/mcctrl/sysfs_files.c +++ b/executer/kernel/mcctrl/sysfs_files.c @@ -679,6 +679,8 @@ static int setup_node_files(struct mcctrl_usrdata *udp) param.ptr = &udp->numa_online; sysfsm_createf(udp->os, SYSFS_SNOOPING_OPS_pbl, ¶m, 0444, "/sys/devices/system/node/online"); + sysfsm_createf(udp->os, SYSFS_SNOOPING_OPS_pbl, ¶m, 0444, + "/sys/devices/system/node/possible"); list_for_each_entry(p, &udp->node_topology_list, chain) { struct sysfs_handle handle; diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 4cf01bc8..fbb082ea 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -1732,6 +1733,63 @@ do_generic_syscall( ret = 0; } + /* Fake that nodeX in /sys/devices/system/node do not exist, + * where X >= number of LWK NUMA nodes */ + else if (w->sr.number == __NR_getdents && ret > 0) { + struct linux_dirent { + long d_ino; + off_t d_off; + unsigned short d_reclen; + char d_name[]; + }; + struct linux_dirent *d; + char *buf = (char *)w->sr.args[1]; + int bpos = 0; + int nodes,len; + char proc_path[PATH_MAX]; + char path[PATH_MAX]; + + sprintf(proc_path, "/proc/self/fd/%d", (int)w->sr.args[0]); + + /* Get filename */ + if ((len = readlink(proc_path, path, sizeof(path))) < 0) { + fprintf(stderr, "%s: error: readlink() failed for %s\n", + __FUNCTION__, proc_path); + goto out; + } + path[len] = 0; + + /* Not /sys/devices/system/node ? */ + if (strcmp(path, "/sys/devices/system/node")) + goto out; + + nodes = ioctl(fd, MCEXEC_UP_GET_NODES, 0); + if (nodes == -1) { + goto out; + } + + d = (struct linux_dirent *) (buf + bpos); + for (bpos = 0; bpos < ret; ) { + int nodeid, tmp_reclen; + d = (struct linux_dirent *) (buf + bpos); + + if (sscanf(d->d_name, "node%d", &nodeid) != 1) { + bpos += d->d_reclen; + continue; + } + + if (nodeid >= nodes) { + tmp_reclen = d->d_reclen; + memmove(buf + bpos, + buf + bpos + tmp_reclen, + ret - bpos - tmp_reclen); + ret -= tmp_reclen; + continue; + } + + bpos += d->d_reclen; + } + } out: __dprintf("do_generic_syscall(%ld):%ld (%#lx)\n", w->sr.number, ret, ret);