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@xxxxxxxxxx> --- 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