NUMA: hide non-existing nodes from /sys/devices/system/node listing
This commit is contained in:
@@ -41,6 +41,7 @@
|
|||||||
#define MCEXEC_UP_NEW_PROCESS 0x30a02909
|
#define MCEXEC_UP_NEW_PROCESS 0x30a02909
|
||||||
#define MCEXEC_UP_GET_CRED 0x30a0290a
|
#define MCEXEC_UP_GET_CRED 0x30a0290a
|
||||||
#define MCEXEC_UP_GET_CREDV 0x30a0290b
|
#define MCEXEC_UP_GET_CREDV 0x30a0290b
|
||||||
|
#define MCEXEC_UP_GET_NODES 0x30a0290c
|
||||||
|
|
||||||
#define MCEXEC_UP_PREPARE_DMA 0x30a02910
|
#define MCEXEC_UP_PREPARE_DMA 0x30a02910
|
||||||
#define MCEXEC_UP_FREE_DMA 0x30a02911
|
#define MCEXEC_UP_FREE_DMA 0x30a02911
|
||||||
|
|||||||
@@ -450,6 +450,16 @@ static long mcexec_get_cpu(ihk_os_t os)
|
|||||||
return info->n_cpus;
|
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,
|
int mcctrl_add_per_proc_data(struct mcctrl_usrdata *ud, int pid,
|
||||||
struct mcctrl_per_proc_data *ppd)
|
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:
|
case MCEXEC_UP_GET_CPU:
|
||||||
return mcexec_get_cpu(os);
|
return mcexec_get_cpu(os);
|
||||||
|
|
||||||
|
case MCEXEC_UP_GET_NODES:
|
||||||
|
return mcexec_get_nodes(os);
|
||||||
|
|
||||||
case MCEXEC_UP_STRNCPY_FROM_USER:
|
case MCEXEC_UP_STRNCPY_FROM_USER:
|
||||||
return mcexec_strncpy_from_user(os,
|
return mcexec_strncpy_from_user(os,
|
||||||
(struct strncpy_from_user_desc *)arg);
|
(struct strncpy_from_user_desc *)arg);
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = {
|
|||||||
{ .request = MCEXEC_UP_LOAD_SYSCALL, .func = mcctrl_ioctl },
|
{ .request = MCEXEC_UP_LOAD_SYSCALL, .func = mcctrl_ioctl },
|
||||||
{ .request = MCEXEC_UP_SEND_SIGNAL, .func = mcctrl_ioctl },
|
{ .request = MCEXEC_UP_SEND_SIGNAL, .func = mcctrl_ioctl },
|
||||||
{ .request = MCEXEC_UP_GET_CPU, .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_STRNCPY_FROM_USER, .func = mcctrl_ioctl },
|
||||||
{ .request = MCEXEC_UP_NEW_PROCESS, .func = mcctrl_ioctl },
|
{ .request = MCEXEC_UP_NEW_PROCESS, .func = mcctrl_ioctl },
|
||||||
{ .request = MCEXEC_UP_PREPARE_DMA, .func = mcctrl_ioctl },
|
{ .request = MCEXEC_UP_PREPARE_DMA, .func = mcctrl_ioctl },
|
||||||
|
|||||||
@@ -679,6 +679,8 @@ static int setup_node_files(struct mcctrl_usrdata *udp)
|
|||||||
param.ptr = &udp->numa_online;
|
param.ptr = &udp->numa_online;
|
||||||
sysfsm_createf(udp->os, SYSFS_SNOOPING_OPS_pbl, ¶m, 0444,
|
sysfsm_createf(udp->os, SYSFS_SNOOPING_OPS_pbl, ¶m, 0444,
|
||||||
"/sys/devices/system/node/online");
|
"/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) {
|
list_for_each_entry(p, &udp->node_topology_list, chain) {
|
||||||
struct sysfs_handle handle;
|
struct sysfs_handle handle;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@@ -1732,6 +1733,63 @@ do_generic_syscall(
|
|||||||
|
|
||||||
ret = 0;
|
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:
|
out:
|
||||||
__dprintf("do_generic_syscall(%ld):%ld (%#lx)\n", w->sr.number, ret, ret);
|
__dprintf("do_generic_syscall(%ld):%ld (%#lx)\n", w->sr.number, ret, ret);
|
||||||
|
|||||||
Reference in New Issue
Block a user