[PATCH v2 23/27] qemu: Wire up MEMORY_DEVICE_SIZE_CHANGE event

Peter Krempa pkrempa at redhat.com
Fri Dec 4 12:59:14 UTC 2020


On Thu, Dec 03, 2020 at 13:36:26 +0100, Michal Privoznik wrote:
> As advertised in previous commit, this event is delivered to us
> when virtio-mem module changes the allocation inside the guest.
> It comes with one attribute - size - which holds the new size of
> the virtio-mem (well, allocated size), in bytes.
> Mind you, this is not necessarily the same number as 'requested
> size'. It almost certainly will be when sizing the memory up, but
> it might not be when sizing the memory down - the guest kernel
> might be unable to free some blocks.
> 
> This actual size is reported in the domain XML as an output
> element only.
> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  docs/formatdomain.rst         |  7 +++
>  docs/schemas/domaincommon.rng |  5 ++
>  src/conf/domain_conf.c        | 24 ++++++++-
>  src/conf/domain_conf.h        |  7 +++
>  src/libvirt_private.syms      |  1 +
>  src/qemu/qemu_domain.c        |  3 ++
>  src/qemu/qemu_domain.h        |  1 +
>  src/qemu/qemu_driver.c        | 36 +++++++++++++
>  src/qemu/qemu_monitor.c       | 24 +++++++++
>  src/qemu/qemu_monitor.h       | 20 ++++++++
>  src/qemu/qemu_monitor_json.c  | 24 +++++++++
>  src/qemu/qemu_process.c       | 96 +++++++++++++++++++++++++++++++----
>  12 files changed, 236 insertions(+), 12 deletions(-)

[...]

> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 8ea7e0df05..1fba9d8302 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -1248,10 +1248,30 @@ 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:
> +            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_LAST:
> +            /* nada */
> +            break;
> +        }
> +    }
> +
>      VIR_DEBUG("Updating balloon from %lld to %lld kb",
>                vm->def->mem.cur_balloon, actual);
>      vm->def->mem.cur_balloon = actual;




> @@ -2405,21 +2466,36 @@ 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:
> +            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_LAST:
> +            /* nada */
> +            break;
> +        }
> +    }
>  
>      vm->def->mem.cur_balloon = balloon;

I don't think we should count the size of virtio-pmem, virtio-mem
against the total VM memory size. The mechanism this is provided to the
VM is different compared to "traditional" dimms. The OS needs driver to
access the memory.

The open question is whether we should add a similar event to what we
have for memballoon change. For now I'd probably not do it since a guest
OS restart (driver unload) can't actually result in more memory consumed
than before.




More information about the libvir-list mailing list