[PATCH v5 12/16] qemu: Account for both memballoon and virtio-mem

Michal Privoznik mprivozn at redhat.com
Mon Sep 13 14:52:40 UTC 2021


Reporting how much memory is exposed to the guest happens under
<currentMemory/> which is taken from def->mem.cur_balloon. The
reported amount should account for both balloon size and the sum
of @currentsize of all virtio-mems. For instance, if domain has
4GiB via balloon and additional 2GiB via virtio-mem, then the
domain XML should report 6GiB. The same applies for domain
statistics.

The way to achieve this is to account for either balloon or
virtio-mem when the size of the other is changed, e.g. on balloon
change we have to add all @currentsize (for non virtio-mem these
will be zero, so the check for memory model is needless, but
makes it more obvious what's happening), and vice versa.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/qemu/qemu_driver.c  |  9 +++++++++
 src/qemu/qemu_process.c | 25 +++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 712ec68f7c..84adeec1c2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4261,6 +4261,7 @@ processMemoryDeviceSizeChange(virQEMUDriver *driver,
 {
     virDomainMemoryDef *mem = NULL;
     virObjectEvent *event = NULL;
+    unsigned long long balloon;
 
     if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
         return;
@@ -4276,7 +4277,15 @@ processMemoryDeviceSizeChange(virQEMUDriver *driver,
         goto endjob;
     }
 
+    /* If this looks weird it's because it is. The balloon size
+     * as reported by QEMU does not include any of @currentsize.
+     * It really contains just the balloon size. But in domain
+     * definition we want to report also sum of @currentsize. Do
+     * a bit of math to fix the domain definition. */
+    balloon = vm->def->mem.cur_balloon - mem->currentsize;
     mem->currentsize = VIR_DIV_UP(info->size, 1024);
+    balloon += mem->currentsize;
+    vm->def->mem.cur_balloon = balloon;
 
     event = virDomainEventMemoryDeviceSizeChangeNewFromObj(vm,
                                                            info->devAlias,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b2ac5937ec..f8e7345329 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1213,10 +1213,22 @@ qemuProcessHandleBalloonChange(qemuMonitor *mon G_GNUC_UNUSED,
     virQEMUDriver *driver = opaque;
     virObjectEvent *event = NULL;
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+    size_t i;
 
     virObjectLock(vm);
     event = virDomainEventBalloonChangeNewFromObj(vm, actual);
 
+    /* We want the balloon size stored in domain definition to
+     * account for the actual size of virtio-mem too. But the
+     * balloon size as reported by QEMU (@actual) contains just
+     * the balloon size without any virtio-mem. Do a wee bit of
+     * math to fix it. */
+    VIR_DEBUG("balloon size before fix is %lld", actual);
+    for (i = 0; i < vm->def->nmems; i++) {
+        if (vm->def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM)
+            actual += vm->def->mems[i]->currentsize;
+    }
+
     VIR_DEBUG("Updating balloon from %lld to %lld kb",
               vm->def->mem.cur_balloon, actual);
     vm->def->mem.cur_balloon = actual;
@@ -2343,6 +2355,7 @@ qemuProcessRefreshBalloonState(virQEMUDriver *driver,
                                int asyncJob)
 {
     unsigned long long balloon;
+    size_t i;
     int rc;
 
     /* if no ballooning is available, the current size equals to the current
@@ -2359,6 +2372,18 @@ qemuProcessRefreshBalloonState(virQEMUDriver *driver,
     if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
         return -1;
 
+    /* We want the balloon size stored in domain definition to
+     * account for the actual size of virtio-mem too. But the
+     * balloon size as reported by QEMU (@balloon) contains just
+     * the balloon size without any virtio-mem. Do a wee bit of
+     * math to fix it. */
+    VIR_DEBUG("balloon size before fix is %lld", balloon);
+    for (i = 0; i < vm->def->nmems; i++) {
+        if (vm->def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM)
+            balloon += vm->def->mems[i]->currentsize;
+    }
+    VIR_DEBUG("Updating balloon from %lld to %lld kb",
+              vm->def->mem.cur_balloon, balloon);
     vm->def->mem.cur_balloon = balloon;
 
     return 0;
-- 
2.32.0




More information about the libvir-list mailing list