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(a)redhat.com>
---
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