[PATCH 08/10] qemu: Recalculate balloon on MEMORY_DEVICE_SIZE_CHANGE event and reconnect

Michal Privoznik mprivozn at redhat.com
Fri Jan 22 12:50:30 UTC 2021


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 at 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




More information about the libvir-list mailing list