Message ID | 1371542991-15911-6-git-send-email-gaowanlong@cn.fujitsu.com |
---|---|
State | New |
Headers | show |
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 <gaowanlong@cn.fujitsu.com> How would this work with mem-path? 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; >
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 <gaowanlong@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; >> > >
Il 18/06/2013 11:44, Wanlong Gao ha scritto: > 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 <gaowanlong@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. Cool, I didn't know this. Thanks. Paolo
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;
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 <gaowanlong@cn.fujitsu.com> --- 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(-)