This QMP command allows user set guest node's memory policy through the QMP protocol. The qmp-shell command is like: set-mem-policy nodeid=0 policy=membind host-nodes=0-1
Signed-off-by: Wanlong Gao <gaowanl...@cn.fujitsu.com> --- numa.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ qapi-schema.json | 19 +++++++++++++++++++ qmp-commands.hx | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) diff --git a/numa.c b/numa.c index 24c886b..3befc56 100644 --- a/numa.c +++ b/numa.c @@ -29,6 +29,7 @@ #include "qapi/opts-visitor.h" #include "qapi/dealloc-visitor.h" #include "exec/memory.h" +#include "qmp-commands.h" #ifdef CONFIG_NUMA #include <numa.h> @@ -378,3 +379,57 @@ void set_numa_modes(void) } } } + +void qmp_set_mem_policy(int64_t nodeid, bool has_policy, const char *policy, + bool has_host_nodes, const char *host_nodes, Error **errp) +{ + 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_policy) { + if (set_node_mem_policy(nodeid) == -1) { + error_setg(errp, "Failed to set memory policy for node%lu", nodeid); + goto error; + } + return; + } + + if (numa_mem_parse_policy(nodeid, policy) == -1) { + error_setg(errp, "Failed to parse memory policy: %s", policy); + goto error; + } + + if (!has_host_nodes) { + bitmap_fill(numa_info[nodeid].host_mem, MAX_CPUMASK_BITS); + } + + if (host_nodes) { + if (numa_mem_parse_hostnodes(nodeid, host_nodes) == -1) { + error_setg(errp, "Failed to parse host nodes range %s", host_nodes); + goto error; + } + } + + if (set_node_mem_policy(nodeid) == -1) { + error_setg(errp, "Failed to set memory policy for node%lu", nodeid); + 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/qapi-schema.json b/qapi-schema.json index 49eac70..fd4c615 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3729,3 +3729,22 @@ '*size': 'size', '*policy': 'str', '*host-nodes': 'str' }} + +## +# @set-mem-policy: +# +# Set the host memory binding policy for guest NUMA node. +# +# @nodeid: The node ID of guest NUMA node to set memory policy to. +# +# @policy: #optional The memory policy to be set (default 'default'). +# +# @host-nodes: #optional The host nodes range for memory policy. +# +# Returns: Nothing on success +# +# Since: 1.6 +## +{ 'command': 'set-mem-policy', + 'data': {'nodeid': 'int', '*policy': 'str', + '*host-nodes': 'str'} } diff --git a/qmp-commands.hx b/qmp-commands.hx index e075df4..aac88e0 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3047,3 +3047,38 @@ Example: <- { "return": {} } EQMP + + { + .name = "set-mem-policy", + .args_type = "nodeid:i,policy:s?,host-nodes:s?", + .help = "Set the host memory binding policy for guest NUMA node", + .mhandler.cmd_new = qmp_marshal_input_set_mem_policy, + }, + +SQMP +set-mem-policy +------ + +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) +- "policy": The memory policy string to set. + (json-string, optional) +- "host-nodes": The host nodes contained to this memory policy. + (json-string, optional) + +Example: + +-> { "execute": "set-mem-policy", "arguments": { "nodeid": 0, "policy": "membind", + "host-nodes": "0-1" }} +<- { "return": {} } + +Notes: + 1. If "policy" is not set, the memory policy of this "nodeid" will be set + to "default". + 2. If "host-nodes" is not set, the node mask of this "policy" will be set + to "all". +EQMP -- 1.8.3.2.634.g7a3187e