On 06/18/2013 05:21 PM, Paolo Bonzini wrote: > Il 18/06/2013 10:09, Wanlong Gao ha scritto: >> The QMP command let it be able to set node's memory policy >> through the QMP protocol. The qmp-shell command is like: >> set-mpol nodeid=0 mpol=membind nodemask=0-1 >> >> Signed-off-by: Wanlong Gao <gaowanl...@cn.fujitsu.com> > > How would this work with mem-path?
This can also set mempolicy for mem-path backed memory in guest nodes. So we don't need to know if we are using mem-path. Thanks, Wanlong Gao > > Paolo > >> --- >> cpus.c | 61 >> +++++++++++++++++++++++++++++++++++++++++++++++++ >> include/sysemu/sysemu.h | 1 + >> qapi-schema.json | 13 +++++++++++ >> qmp-commands.hx | 35 ++++++++++++++++++++++++++++ >> vl.c | 2 +- >> 5 files changed, 111 insertions(+), 1 deletion(-) >> >> diff --git a/cpus.c b/cpus.c >> index b868932..a2836e9 100644 >> --- a/cpus.c >> +++ b/cpus.c >> @@ -1431,3 +1431,64 @@ void qmp_inject_nmi(Error **errp) >> error_set(errp, QERR_UNSUPPORTED); >> #endif >> } >> + >> +void qmp_set_mpol(int64_t nodeid, bool has_mpol, const char *mpol, >> + bool has_nodemask, const char *nodemask, Error **errp) >> +{ >> + unsigned int ret; >> + unsigned int flags; >> + DECLARE_BITMAP(host_mem, MAX_CPUMASK_BITS); >> + >> + if (nodeid >= nb_numa_nodes) { >> + error_setg(errp, "Only has '%d' NUMA nodes", nb_numa_nodes); >> + return; >> + } >> + >> + bitmap_copy(host_mem, numa_info[nodeid].host_mem, MAX_CPUMASK_BITS); >> + flags = numa_info[nodeid].flags; >> + >> + numa_info[nodeid].flags = NODE_HOST_NONE; >> + bitmap_zero(numa_info[nodeid].host_mem, MAX_CPUMASK_BITS); >> + >> + if (!has_mpol) { >> + if (set_node_mpol(nodeid) == -1) { >> + goto error; >> + } >> + return; >> + } >> + >> + if (!strcmp(mpol, "membind")) { >> + numa_info[nodeid].flags |= NODE_HOST_BIND; >> + } else if (!strcmp(mpol, "interleave")) { >> + numa_info[nodeid].flags |= NODE_HOST_INTERLEAVE; >> + } else if (!strcmp(mpol, "preferred")) { >> + numa_info[nodeid].flags |= NODE_HOST_PREFERRED; >> + } else { >> + error_setg(errp, "Invalid NUMA policy '%s'", mpol); >> + goto error; >> + } >> + >> + if (!has_nodemask) { >> + bitmap_fill(numa_info[nodeid].host_mem, MAX_CPUMASK_BITS); >> + } >> + >> + if (nodemask) { >> + ret = numa_node_parse_mpol(nodemask, numa_info[nodeid].host_mem); >> + } >> + if (ret == 4) { >> + goto error; >> + } else if (ret & 1) { >> + numa_info[nodeid].flags |= NODE_HOST_RELATIVE; >> + } >> + >> + if (set_node_mpol(nodeid) == -1) { >> + goto error; >> + } >> + >> + return; >> + >> +error: >> + bitmap_copy(numa_info[nodeid].host_mem, host_mem, MAX_CPUMASK_BITS); >> + numa_info[nodeid].flags = flags; >> + return; >> +} >> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h >> index 993b8e0..7d804af 100644 >> --- a/include/sysemu/sysemu.h >> +++ b/include/sysemu/sysemu.h >> @@ -144,6 +144,7 @@ struct node_info { >> unsigned int flags; >> }; >> extern struct node_info numa_info[MAX_NODES]; >> +extern unsigned int numa_node_parse_mpol(const char *str, unsigned long >> *bm); >> >> #define MAX_OPTION_ROMS 16 >> typedef struct QEMUOptionRom { >> diff --git a/qapi-schema.json b/qapi-schema.json >> index a80ee40..403c703 100644 >> --- a/qapi-schema.json >> +++ b/qapi-schema.json >> @@ -3608,3 +3608,16 @@ >> '*cpuid-input-ecx': 'int', >> 'cpuid-register': 'X86CPURegister32', >> 'features': 'int' } } >> + >> +# @set-mpol: >> +# >> +# Set the host memory binding policy for guest NUMA node. >> +# >> +# @node-id: The node ID of guest NUMA node to set memory policy to. >> +# >> +# @mpol: The memory policy string to set. >> +# >> +# Since: 1.6.0 >> +## >> +{ 'command': 'set-mpol', 'data': {'nodeid': 'int', '*mpol': 'str', >> + '*nodemask': 'str'} } >> diff --git a/qmp-commands.hx b/qmp-commands.hx >> index 8cea5e5..930c844 100644 >> --- a/qmp-commands.hx >> +++ b/qmp-commands.hx >> @@ -2997,3 +2997,38 @@ Example: >> <- { "return": {} } >> >> EQMP >> + >> + { >> + .name = "set-mpol", >> + .args_type = "nodeid:i,mpol:s?,nodemask:s?", >> + .help = "Set the host memory binding policy for guest NUMA >> node", >> + .mhandler.cmd_new = qmp_marshal_input_set_mpol, >> + }, >> + >> +SQMP >> +set-mpol >> +------ >> + >> +Set the host memory binding policy for guest NUMA node >> + >> +Arguments: >> + >> +- "nodeid": The nodeid of guest NUMA node to set memory policy to. >> + (json-int) >> +- "mpol": The memory policy string to set. >> + (json-string, optional) >> +- "nodemask": The node mask contained to mpol. >> + (json-string, optional) >> + >> +Example: >> + >> +-> { "execute": "set-mpol", "arguments": { "nodeid": 0, "mpol": "membind", >> + "nodemask": "0-1" }} >> +<- { "return": {} } >> + >> +Notes: >> + 1. If "mpol" is not set, the memory policy of this "nodeid" will be set >> + to "default". >> + 2. If "nodemask" is not set, the node mask of this "mpol" will be set >> + to "all". >> +EQMP >> diff --git a/vl.c b/vl.c >> index ada9fb2..73af85e 100644 >> --- a/vl.c >> +++ b/vl.c >> @@ -1348,7 +1348,7 @@ error: >> exit(1); >> } >> >> -static unsigned int numa_node_parse_mpol(const char *str, unsigned long *bm) >> +unsigned int numa_node_parse_mpol(const char *str, unsigned long *bm) >> { >> unsigned long long value, endvalue; >> char *endptr; >> > >