Just like we are recalculating the amount of guest memory on BALLOON_CHANGE and on reconnect to the monitor, we should include the actual size of virtio-mem too. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/qemu/qemu_driver.c | 3 +++ src/qemu/qemu_process.c | 57 +++++++++++++++++++++++++++++++++-------- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d64eb4d399..2fd4429ba8 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4298,6 +4298,9 @@ processMemoryDeviceSizeChange(virQEMUDriverPtr driver, mem = vm->def->mems[idx]; mem->actualsize = VIR_DIV_UP(info->size, 1024); + /* fix the balloon size */ + ignore_value(qemuProcessRefreshBalloonState(driver, vm, QEMU_ASYNC_JOB_NONE)); + endjob: qemuDomainObjEndJob(driver, vm); } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 8d41f947af..01d261d538 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1250,10 +1250,31 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon G_GNUC_UNUSED, virQEMUDriverPtr driver = opaque; virObjectEventPtr event = NULL; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + size_t i; virObjectLock(vm); event = virDomainEventBalloonChangeNewFromObj(vm, actual); + VIR_DEBUG("New balloon size before fixup: %lld", actual); + + for (i = 0; i < vm->def->nmems; i++) { + virDomainMemoryDefPtr mem = vm->def->mems[i]; + + switch (mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + actual += mem->actualsize; + break; + + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + /* nada */ + break; + } + } + VIR_DEBUG("Updating balloon from %lld to %lld kb", vm->def->mem.cur_balloon, actual); vm->def->mem.cur_balloon = actual; @@ -2451,21 +2472,37 @@ qemuProcessRefreshBalloonState(virQEMUDriverPtr driver, int asyncJob) { unsigned long long balloon; + size_t i; int rc; - /* if no ballooning is available, the current size equals to the current - * full memory size */ - if (!virDomainDefHasMemballoon(vm->def)) { - vm->def->mem.cur_balloon = virDomainDefGetMemoryTotal(vm->def); - return 0; + if (virDomainDefHasMemballoon(vm->def)) { + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + rc = qemuMonitorGetBalloonInfo(qemuDomainGetMonitor(vm), &balloon); + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + return -1; + } else { + balloon = virDomainDefGetMemoryTotal(vm->def); } - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) - return -1; + for (i = 0; i < vm->def->nmems; i++) { + virDomainMemoryDefPtr mem = vm->def->mems[i]; + + switch (mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + balloon += mem->actualsize; + break; - rc = qemuMonitorGetBalloonInfo(qemuDomainGetMonitor(vm), &balloon); - if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) - return -1; + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + /* nada */ + break; + } + } vm->def->mem.cur_balloon = balloon; -- 2.26.2