From 198c1eb6b4b7a7602641a73f56d6e6c191a3641c Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Wed, 18 Nov 2020 16:58:34 -0300 Subject: [PATCH] qemu_domain.c: align all pSeries mem modules when PARSE_ABI_UPDATE qemuDomainAlignMemorySizes() has an operation order problem. We are calculating 'initialmem' without aligning the memory modules first. Since we're aligning the dimms afterwards this can create inconsistencies in the end result. x86 has alignment of 1-2MiB and it's not severely impacted by it, but pSeries works with 256MiB alignment and the difference is noticeable. This is the case of the existing 'memory-hotplug-ppc64-nonuma' test. The test consists of a 2GiB (aligned value) guest with 2 ~520MiB dimms, both unaligned. 'initialmem' is calculated by taking total_mem and subtracting the dimms size (via virDomainDefGetMemoryInitial()), which wil give us 2GiB - 520MiB - 520MiB, ending up with a little more than an 1GiB of 'initialmem'. Note that this value is now unaligned, and will be aligned up via VIR_ROUND_UP(), and we'll end up with 'initialmem' of 1GiB + 256MiB. Given that the dimms are aligned later on, the end result for QEMU is that the guest will have a 'mem' size of 1310720k, plus the two 512 MiB dimms, exceeding in 256MiB the desired 2GiB memory and currentMemory specified in the XML. Existing guests can't be fixed without breaking ABI, but we have code already in place to align pSeries NVDIMM modules for new guests. Let's extend it to align all pSeries mem modules. A new test, 'memory-hotplug-ppc64-nonuma-abi-update', a copy of the existing 'memory-hotplug-ppc64-nonuma', was added to demonstrate the result for new pSeries guests. For the same unaligned XML mentioned above, after applying this patch: - starting QEMU mem size without PARSE_ABI_UPDATE: -m size=1310720k,slots=16,maxmem=4194304k \ (no changes) - starting QEMU mem size with PARSE_ABI_UPDATE: -m size=1048576k,slots=16,maxmem=4194304k \ (size fixed) Reviewed-by: Andrea Bolognani Reviewed-by: Michal Privoznik Signed-off-by: Daniel Henrique Barboza --- src/qemu/qemu_domain.c | 14 +++++-- ...emory-hotplug-ppc64-nonuma-abi-update.args | 29 ++++++++++++++ ...memory-hotplug-ppc64-nonuma-abi-update.xml | 1 + tests/qemuxml2argvtest.c | 7 ++++ ...memory-hotplug-ppc64-nonuma-abi-update.xml | 38 +++++++++++++++++++ tests/qemuxml2xmltest.c | 7 ++++ 6 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args create mode 120000 tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.xml create mode 100644 tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 6ea0fecd12..dcc68f486d 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5358,10 +5358,16 @@ qemuDomainMemoryDefPostParse(virDomainMemoryDefPtr mem, virArch arch, * later on by qemuDomainAlignMemorySizes() to contemplate existing * guests as well. */ if (parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE) { - if (ARCH_IS_PPC64(arch) && - mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM && - virDomainNVDimmAlignSizePseries(mem) < 0) - return -1; + if (ARCH_IS_PPC64(arch)) { + unsigned long long ppc64MemModuleAlign = 256 * 1024; + + if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM) { + if (virDomainNVDimmAlignSizePseries(mem) < 0) + return -1; + } else { + mem->size = VIR_ROUND_UP(mem->size, ppc64MemModuleAlign); + } + } } return 0; diff --git a/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args b/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args new file mode 100644 index 0000000000..ac741b80c0 --- /dev/null +++ b/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args @@ -0,0 +1,29 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-ppc64 \ +-name QEMUGuest1 \ +-S \ +-machine pseries,accel=kvm,usb=off,dump-guest-core=off \ +-m size=1048576k,slots=16,maxmem=4194304k \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-object memory-backend-ram,id=memdimm0,size=536870912 \ +-device pc-dimm,memdev=memdimm0,id=dimm0,slot=0 \ +-object memory-backend-ram,id=memdimm1,size=536870912 \ +-device pc-dimm,memdev=memdimm1,id=dimm1,slot=1 \ +-uuid 49545eb3-75e1-2d0a-acdd-f0294406c99e \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown diff --git a/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.xml b/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.xml new file mode 120000 index 0000000000..03410026cc --- /dev/null +++ b/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.xml @@ -0,0 +1 @@ +memory-hotplug-ppc64-nonuma.xml \ No newline at end of file diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index a9bd210ca3..7c9dc0e641 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3005,6 +3005,13 @@ mymain(void) DO_TEST("memory-hotplug-ppc64-nonuma", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE_PC_DIMM, QEMU_CAPS_NUMA, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE); + DO_TEST_FULL("memory-hotplug-ppc64-nonuma-abi-update", + ARG_PARSEFLAGS, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, + ARG_QEMU_CAPS, + QEMU_CAPS_KVM, QEMU_CAPS_DEVICE_PC_DIMM, + QEMU_CAPS_NUMA, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_OBJECT_MEMORY_RAM, + QEMU_CAPS_OBJECT_MEMORY_FILE); DO_TEST_CAPS_LATEST("memory-hotplug-nvdimm"); DO_TEST_CAPS_LATEST("memory-hotplug-nvdimm-access"); DO_TEST_CAPS_LATEST("memory-hotplug-nvdimm-label"); diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml b/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml new file mode 100644 index 0000000000..4edb786e6f --- /dev/null +++ b/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml @@ -0,0 +1,38 @@ + + QEMUGuest1 + 49545eb3-75e1-2d0a-acdd-f0294406c99e + 4194304 + 2097152 + 2097152 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-ppc64 + + + + + + + + + + 524288 + +
+ + + + 524288 + +
+ + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 18faea2b33..1968be6782 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1232,6 +1232,13 @@ mymain(void) DO_TEST("memory-hotplug-ppc64-nonuma", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE_PC_DIMM, QEMU_CAPS_NUMA, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE); + DO_TEST_FULL("memory-hotplug-ppc64-nonuma-abi-update", WHEN_BOTH, + ARG_PARSEFLAGS, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, + ARG_QEMU_CAPS, + QEMU_CAPS_KVM, QEMU_CAPS_DEVICE_PC_DIMM, + QEMU_CAPS_NUMA, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_OBJECT_MEMORY_RAM, + QEMU_CAPS_OBJECT_MEMORY_FILE, QEMU_CAPS_LAST); DO_TEST("memory-hotplug", NONE); DO_TEST("memory-hotplug-dimm", QEMU_CAPS_DEVICE_PC_DIMM); DO_TEST("memory-hotplug-nvdimm", QEMU_CAPS_DEVICE_NVDIMM);