[libvirt] [PATCH 4/7] qemu: conf: Cache domCaps in qemuCaps
Daniel Henrique Barboza
danielhb413 at gmail.com
Fri Apr 26 20:58:36 UTC 2019
On 4/4/19 8:37 PM, Cole Robinson wrote:
> qemuCaps is tied to a binary on disk. domCaps is tied to a combo
> of binary+machine+arch+virttype values. For the qemu driver this almost
> entirely translates to a permutation of qemuCaps though
>
> Upcoming patches want to use the domCaps data store at XML validate
> time, but we need to cache the data so we aren't repeatedly
> regenerating it.
>
> Add a domCapsCache hash table to qemuCaps. This ensures that the domCaps
> cache is blown away whenever qemuCaps needs to be regenerated. Adjust
> virQEMUDriverGetDomainCapabilities to search the cache and add to it
> if we don't find a hit.
>
> Signed-off-by: Cole Robinson <crobinso at redhat.com>
Nit: there is a 80+ char line at the start of virQEMUDriverSearchDomcaps,
but I'm not sure if this is more like a "nice to have" rule or if it's
enforced like in QEMU.
Reviewed-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
> ---
> src/qemu/qemu_capabilities.c | 11 +++++++
> src/qemu/qemu_capabilities.h | 1 +
> src/qemu/qemu_conf.c | 59 +++++++++++++++++++++++++++++++-----
> 3 files changed, 64 insertions(+), 7 deletions(-)
>
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 46ba5e30b5..a3c1348157 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -582,6 +582,7 @@ struct _virQEMUCaps {
>
> virArch arch;
>
> + virHashTablePtr domCapsCache;
> virDomainCapsCPUModelsPtr kvmCPUModels;
> virDomainCapsCPUModelsPtr tcgCPUModels;
>
> @@ -1476,6 +1477,9 @@ virQEMUCapsNew(void)
> if (!(qemuCaps->flags = virBitmapNew(QEMU_CAPS_LAST)))
> goto error;
>
> + if (!(qemuCaps->domCapsCache = virHashCreate(5, virObjectFreeHashData)))
> + goto error;
> +
> return qemuCaps;
>
> error:
> @@ -1628,6 +1632,7 @@ void virQEMUCapsDispose(void *obj)
> }
> VIR_FREE(qemuCaps->machineTypes);
>
> + virHashFree(qemuCaps->domCapsCache);
> virObjectUnref(qemuCaps->kvmCPUModels);
> virObjectUnref(qemuCaps->tcgCPUModels);
>
> @@ -1790,6 +1795,12 @@ const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps)
> }
>
>
> +virHashTablePtr virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps)
> +{
> + return qemuCaps->domCapsCache;
> +}
> +
> +
> int
> virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
> virDomainVirtType type,
> diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
> index c6f6980684..2a37f0c2ff 100644
> --- a/src/qemu/qemu_capabilities.h
> +++ b/src/qemu/qemu_capabilities.h
> @@ -538,6 +538,7 @@ const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps);
> virArch virQEMUCapsGetArch(virQEMUCapsPtr qemuCaps);
> unsigned int virQEMUCapsGetVersion(virQEMUCapsPtr qemuCaps);
> const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps);
> +virHashTablePtr virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps);
> unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps);
> int virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
> virDomainVirtType type,
> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> index 635fdcc5a4..6a7c183075 100644
> --- a/src/qemu/qemu_conf.c
> +++ b/src/qemu/qemu_conf.c
> @@ -1358,10 +1358,39 @@ virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
> }
>
>
> +struct virQEMUDriverSearchDomcapsData {
> + const char *path;
> + const char *machine;
> + virArch arch;
> + virDomainVirtType virttype;
> +};
> +
> +
> +static int
> +virQEMUDriverSearchDomcaps(const void *payload,
> + const void *name ATTRIBUTE_UNUSED,
> + const void *opaque)
> +{
> + virDomainCapsPtr domCaps = (virDomainCapsPtr) payload;
> + struct virQEMUDriverSearchDomcapsData *data = (struct virQEMUDriverSearchDomcapsData *) opaque;
> +
> + if (STREQ_NULLABLE(data->path, domCaps->path) &&
> + STREQ_NULLABLE(data->machine, domCaps->machine) &&
> + data->arch == domCaps->arch &&
> + data->virttype == domCaps->virttype)
> + return 1;
> +
> + return 0;
> +}
> +
> /**
> * virQEMUDriverGetDomainCapabilities:
> *
> - * Build a virDomainCapsPtr instance for the passed data.
> + * Get a reference to the virDomainCapsPtr instance from the virQEMUCapsPtr
> + * domCapsCache. If there's no domcaps in the cache, create a new instance,
> + * add it to the cache, and return a reference.
> + *
> + * The caller must release the reference with virObjetUnref
> *
> * Returns: a reference to a virDomainCapsPtr instance or NULL
> */
> @@ -1375,18 +1404,34 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriverPtr driver,
> virDomainCapsPtr ret = NULL, domCaps = NULL;
> virCapsPtr caps = NULL;
> virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> + virHashTablePtr domCapsCache = virQEMUCapsGetDomainCapsCache(qemuCaps);
> + struct virQEMUDriverSearchDomcapsData data = {
> + .path = virQEMUCapsGetBinary(qemuCaps),
> + .machine = machine,
> + .arch = arch,
> + .virttype = virttype,
> + };
>
> if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
> goto cleanup;
>
> - if (!(domCaps = virDomainCapsNew(virQEMUCapsGetBinary(qemuCaps), machine,
> - arch, virttype)))
> - goto cleanup;
> + domCaps = virHashSearch(domCapsCache,
> + virQEMUDriverSearchDomcaps, &data, NULL);
> + if (!domCaps) {
> + /* hash miss, build new domcaps */
> + if (!(domCaps = virDomainCapsNew(data.path, data.machine,
> + data.arch, data.virttype)))
> + goto cleanup;
>
> - if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
> - cfg->firmwares, cfg->nfirmwares) < 0)
> - goto cleanup;
> + if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
> + cfg->firmwares, cfg->nfirmwares) < 0)
> + goto cleanup;
> +
> + if (virHashAddEntry(domCapsCache, machine, domCaps) < 0)
> + goto cleanup;
> + }
>
> + virObjectRef(domCaps);
> VIR_STEAL_PTR(ret, domCaps);
> cleanup:
> virObjectUnref(domCaps);
More information about the libvir-list
mailing list