@@ -146,5 +146,6 @@ void hmp_info_ramblock(Monitor *mon, const QDict *qdict);
void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
+void hmp_set_numa_node(Monitor *mon, const QDict *qdict);
#endif
@@ -1837,6 +1837,19 @@ Print QOM properties of object at location @var{path}
ETEXI
{
+ .name = "set-numa-node",
+ .args_type = "numa:O",
+ .params = "see -numa CLI option for possible options",
+ .help = "assign CPU to numa node",
+ .cmd = hmp_set_numa_node,
+ },
+
+STEXI
+@item qom-set @var{path} @var{property} @var{value}
+Set QOM property @var{property} of object at location @var{path} to value @var{value}
+ETEXI
+
+ {
.name = "qom-set",
.args_type = "path:s,property:s,value:s",
.params = "path property value",
@@ -43,6 +43,7 @@
#include "hw/intc/intc.h"
#include "migration/snapshot.h"
#include "migration/misc.h"
+#include "sysemu/numa.h"
#ifdef CONFIG_SPICE
#include <spice/enums.h>
@@ -2896,3 +2897,25 @@ void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict)
}
hmp_handle_error(mon, &err);
}
+
+void hmp_set_numa_node(Monitor *mon, const QDict *qdict)
+{
+ QemuOpts *opts;
+ Error *err = NULL;
+ MachineState *ms = MACHINE(qdev_get_machine());
+
+ opts = qemu_opts_from_qdict(qemu_find_opts("numa"), qdict, &err);
+ if (err) {
+ goto end;
+ }
+
+ parse_numa(ms, opts, &err);
+ if (err) {
+ goto end;
+ }
+
+end:
+ if (err) {
+ hmp_handle_error(mon, &err);
+ }
+}
@@ -47,6 +47,12 @@ QemuOptsList qemu_numa_opts = {
.desc = { { 0 } } /* validated with OptsVisitor */
};
+static enum {
+ NUMA_DISABLED, /* no numa was configured */
+ NUMA_ENABLED, /* numa configuration is in process */
+ NUMA_COMPLETE, /* configuration is complete and can't be altered */
+} numa_is_configured;
+
static int have_memdevs = -1;
static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one.
* For all nodes, nodeid < max_numa_nodeid
@@ -259,6 +265,18 @@ void parse_NumaOptions(MachineState *ms, NumaOptions *object, Error **errp)
{
Error *err = NULL;
+ if (numa_is_configured == NUMA_COMPLETE) {
+ error_setg(&err, "NUMA configuration is finalized and can't be changed,"
+ " use CLI option or set-numa-node HMP/QMP command at"
+ " preconfig stage");
+ goto end;
+ } else if (runstate_check(RUN_STATE_PRELAUNCH)) {
+ numa_is_configured = NUMA_ENABLED;
+ } else {
+ error_setg(&err, "NUMA is not enabled at start/preconfig stage");
+ goto end;
+ }
+
switch (object->type) {
case NUMA_OPTIONS_TYPE_NODE:
parse_numa_node(ms, &object->u.node, &err);
@@ -512,6 +530,7 @@ void numa_complete_configuration(MachineState *ms)
} else {
numa_set_mem_node_id(0, ram_size, 0);
}
+ numa_is_configured = NUMA_COMPLETE;
}
void parse_numa_opts(MachineState *ms)
Signed-off-by: Igor Mammedov <imammedo@redhat.com> --- hmp.h | 1 + hmp-commands.hx | 13 +++++++++++++ hmp.c | 23 +++++++++++++++++++++++ numa.c | 19 +++++++++++++++++++ 4 files changed, 56 insertions(+)