Up until v2.11.0-rc2~19^2~3 QEMU used to require at least one
NUMA node to be configured when memory hotplug was enabled. After
that commit, QEMU automatically adds a NUMA node if none was
specified on the cmd line. Reflect this in domain XML, i.e.
explicitly add a NUMA node into our domain definition if needed.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_domain.c | 53 ++++++++++++++++++-
...emory-hotplug-ppc64-nonuma-abi-update.args | 11 ++--
...memory-hotplug-ppc64-nonuma-abi-update.xml | 7 ++-
3 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 3700b3e711..a9ed5f5901 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4807,6 +4807,51 @@ qemuDomainDefTsegPostParse(virDomainDef *def,
}
+static int
+qemuDomainDefNumaAutoAdd(virDomainDef *def,
+ unsigned int parseFlags)
+{
+ bool abiUpdate = !!(parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE);
+ unsigned long long initialMem;
+ size_t i;
+
+ if (!abiUpdate ||
+ !virDomainDefHasMemoryHotplug(def) ||
+ virDomainNumaGetNodeCount(def->numa) > 0) {
+ return 0;
+ }
+
+ initialMem = virDomainDefGetMemoryInitial(def);
+
+ if (!def->numa)
+ def->numa = virDomainNumaNew();
+
+ virDomainNumaSetNodeCount(def->numa, 1);
+ virDomainNumaSetNodeMemorySize(def->numa, 0, initialMem);
+
+ for (i = 0; i < def->nmems; i++) {
+ virDomainMemoryDef *mem = def->mems[i];
+
+ switch (mem->model) {
+ case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+ case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+ case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+ if (mem->targetNode == -1)
+ mem->targetNode = 0;
+ break;
+
+ case VIR_DOMAIN_MEMORY_MODEL_NONE:
+ case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+ case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
+ case VIR_DOMAIN_MEMORY_MODEL_LAST:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
/**
* qemuDomainDefNumaCPUsRectify:
* @numa: pointer to numa definition
@@ -4841,8 +4886,12 @@ qemuDomainDefNumaCPUsRectify(virDomainDef *def,
static int
qemuDomainDefNumaCPUsPostParse(virDomainDef *def,
- virQEMUCaps *qemuCaps)
+ virQEMUCaps *qemuCaps,
+ unsigned int parseFlags)
{
+ if (qemuDomainDefNumaAutoAdd(def, parseFlags) < 0)
+ return -1;
+
return qemuDomainDefNumaCPUsRectify(def, qemuCaps);
}
@@ -4914,7 +4963,7 @@ qemuDomainDefPostParse(virDomainDef *def,
if (qemuDomainDefTsegPostParse(def, qemuCaps) < 0)
return -1;
- if (qemuDomainDefNumaCPUsPostParse(def, qemuCaps) < 0)
+ if (qemuDomainDefNumaCPUsPostParse(def, qemuCaps, parseFlags) < 0)
return -1;
return 0;
diff --git a/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args
b/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args
index 83bfb1123c..18ae15aa0b 100644
--- a/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args
+++ b/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args
@@ -10,13 +10,14 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-name guest=QEMUGuest1,debug-threads=on \
-S \
-object
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}'
\
--machine pseries,usb=off,dump-guest-core=off,memory-backend=ppc_spapr.ram \
+-machine pseries,usb=off,dump-guest-core=off \
-accel kvm \
-cpu POWER9 \
--m size=1048576k,slots=16,maxmem=4194304k \
--object
'{"qom-type":"memory-backend-ram","id":"ppc_spapr.ram","size":1073741824}'
\
+-m size=1310720k,slots=16,maxmem=4194304k \
-overcommit mem-lock=off \
-smp 1,sockets=1,cores=1,threads=1 \
+-object
'{"qom-type":"memory-backend-ram","id":"ram-node0","size":1342177280}'
\
+-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
-uuid 49545eb3-75e1-2d0a-acdd-f0294406c99e \
-display none \
-no-user-config \
@@ -27,9 +28,9 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-no-shutdown \
-boot strict=on \
-object
'{"qom-type":"memory-backend-ram","id":"memdimm0","size":536870912}'
\
--device
'{"driver":"pc-dimm","memdev":"memdimm0","id":"dimm0","slot":0}'
\
+-device
'{"driver":"pc-dimm","node":0,"memdev":"memdimm0","id":"dimm0","slot":0}'
\
-object
'{"qom-type":"memory-backend-ram","id":"memdimm1","size":536870912}'
\
--device
'{"driver":"pc-dimm","memdev":"memdimm1","id":"dimm1","slot":1}'
\
+-device
'{"driver":"pc-dimm","node":0,"memdev":"memdimm1","id":"dimm1","slot":1}'
\
-audiodev
'{"id":"audio1","driver":"none"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml
b/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml
index d0be98f140..c4677dc977 100644
--- a/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml
+++ b/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml
@@ -2,7 +2,7 @@
<name>QEMUGuest1</name>
<uuid>49545eb3-75e1-2d0a-acdd-f0294406c99e</uuid>
<maxMemory slots='16' unit='KiB'>4194304</maxMemory>
- <memory unit='KiB'>2097152</memory>
+ <memory unit='KiB'>2098177</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
@@ -11,6 +11,9 @@
</os>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>POWER9</model>
+ <numa>
+ <cell id='0' cpus='0' memory='1049601'
unit='KiB'/>
+ </numa>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
@@ -29,12 +32,14 @@
<memory model='dimm'>
<target>
<size unit='KiB'>524288</size>
+ <node>0</node>
</target>
<address type='dimm' slot='0'/>
</memory>
<memory model='dimm'>
<target>
<size unit='KiB'>524288</size>
+ <node>0</node>
</target>
<address type='dimm' slot='1'/>
</memory>
--
2.41.0