[libvirt] [PATCH 1/3] qemu: cgroup: Extract temporary relaxing of cgroup setting for vcpu hotplug
Boris Fiuczynski
fiuczy at linux.vnet.ibm.com
Tue Sep 13 09:11:12 UTC 2016
On 09/07/2016 02:04 PM, Peter Krempa wrote:
> When hot-adding vcpus qemu needs to allocate some structures in the DMA
> zone which may be outside of the numa pinning. Extract the code doing
> this in a set of helpers so that it can be reused.
> ---
> src/qemu/qemu_cgroup.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++
> src/qemu/qemu_cgroup.h | 11 ++++++
> src/qemu/qemu_driver.c | 36 +++-----------------
> 3 files changed, 105 insertions(+), 32 deletions(-)
>
> diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
> index 2dca874..e2b5bab 100644
> --- a/src/qemu/qemu_cgroup.c
> +++ b/src/qemu/qemu_cgroup.c
> @@ -1127,3 +1127,93 @@ qemuRemoveCgroup(virDomainObjPtr vm)
>
> return virCgroupRemove(priv->cgroup);
> }
> +
> +
> +static void
> +qemuCgroupEmulatorAllNodesDataFree(qemuCgroupEmulatorAllNodesDataPtr data)
> +{
> + if (!data)
> + return;
> +
> + virCgroupFree(&data->emulatorCgroup);
> + VIR_FREE(data->emulatorMemMask);
> + VIR_FREE(data);
> +}
> +
> +
> +/**
> + * qemuCgroupEmulatorAllNodesAllow:
> + * @cgroup: domain cgroup pointer
> + * @retData: filled with structure used to roll back the operation
> + *
> + * Allows all NUMA nodes for the qemu emulator thread temporarily. This is
> + * necessary when hotplugging cpus since it requires memory allocated in the
> + * DMA region. Afterwards the operation can be reverted by
> + * qemuCgrouEmulatorAllNodesRestore.
> + *
> + * Returns 0 on success -1 on error
> + */
> +int
> +qemuCgroupEmulatorAllNodesAllow(virCgroupPtr cgroup,
> + qemuCgroupEmulatorAllNodesDataPtr *retData)
> +{
> + qemuCgroupEmulatorAllNodesDataPtr data = NULL;
> + char *all_nodes_str = NULL;
> + virBitmapPtr all_nodes = NULL;
> + int ret = -1;
> +
> + if (!virNumaIsAvailable() ||
> + !virCgroupHasController(cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
> + return 0;
> +
> + if (!(all_nodes = virNumaGetHostNodeset()))
> + goto cleanup;
> +
> + if (!(all_nodes_str = virBitmapFormat(all_nodes)))
> + goto cleanup;
> +
> + if (VIR_ALLOC(data) < 0)
> + goto cleanup;
> +
> + if (virCgroupNewThread(cgroup, VIR_CGROUP_THREAD_EMULATOR, 0,
> + false, &data->emulatorCgroup) < 0)
> + goto cleanup;
> +
> + if (virCgroupGetCpusetMems(data->emulatorCgroup, &data->emulatorMemMask) < 0 ||
> + virCgroupSetCpusetMems(data->emulatorCgroup, all_nodes_str) < 0)
> + goto cleanup;
> +
> + VIR_STEAL_PTR(*retData, data);
> + ret = 0;
> +
> + cleanup:
> + VIR_FREE(all_nodes_str);
> + virBitmapFree(all_nodes);
> + qemuCgroupEmulatorAllNodesDataFree(data);
> +
> + return ret;
> +}
> +
> +
> +/**
> + * qemuCgrouEmulatorAllNodesRestore:
qemuCgrou p EmulatorAllNodesRestore???
> + * @data: data structure created by qemuCgroupEmulatorAllNodesAllow
> + *
> + * Rolls back the setting done by qemuCgroupEmulatorAllNodesAllow and frees the
> + * associated data.
> + */
> +void
> +qemuCgrouEmulatorAllNodesRestore(qemuCgroupEmulatorAllNodesDataPtr data)
> +{
> + virErrorPtr err;
> +
> + if (!data)
> + return;
> +
> + err = virSaveLastError();
> + virCgroupSetCpusetMems(data->emulatorCgroup, data->emulatorMemMask);
> + virSetError(err);
> + virFreeError(err);
> +
> + qemuCgroupEmulatorAllNodesDataFree(data);
> +}
> diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
> index dc340a1..e6ebae0 100644
> --- a/src/qemu/qemu_cgroup.h
> +++ b/src/qemu/qemu_cgroup.h
> @@ -57,4 +57,15 @@ int qemuSetupCgroupCpusetCpus(virCgroupPtr cgroup, virBitmapPtr cpumask);
> int qemuSetupGlobalCpuCgroup(virDomainObjPtr vm);
> int qemuRemoveCgroup(virDomainObjPtr vm);
>
> +typedef struct _qemuCgroupEmulatorAllNodesData qemuCgroupEmulatorAllNodesData;
> +typedef qemuCgroupEmulatorAllNodesData *qemuCgroupEmulatorAllNodesDataPtr;
> +struct _qemuCgroupEmulatorAllNodesData {
> + virCgroupPtr emulatorCgroup;
> + char *emulatorMemMask;
> +};
> +
> +int qemuCgroupEmulatorAllNodesAllow(virCgroupPtr cgroup,
> + qemuCgroupEmulatorAllNodesDataPtr *data);
> +void qemuCgrouEmulatorAllNodesRestore(qemuCgroupEmulatorAllNodesDataPtr data);
> +
> #endif /* __QEMU_CGROUP_H__ */
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 807e06d..07d33d3 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -4853,11 +4853,7 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
> unsigned int nvcpus)
> {
> qemuDomainObjPrivatePtr priv = vm->privateData;
> - virCgroupPtr cgroup_temp = NULL;
> - char *mem_mask = NULL;
> - char *all_nodes_str = NULL;
> - virBitmapPtr all_nodes = NULL;
> - virErrorPtr err = NULL;
> + qemuCgroupEmulatorAllNodesDataPtr emulatorCgroup = NULL;
> virBitmapPtr vcpumap = NULL;
> ssize_t nextvcpu = -1;
> int rc = 0;
> @@ -4866,22 +4862,8 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
> if (!(vcpumap = qemuDomainSelectHotplugVcpuEntities(vm->def, nvcpus)))
> goto cleanup;
>
> - if (virNumaIsAvailable() &&
> - virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
> - if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_EMULATOR, 0,
> - false, &cgroup_temp) < 0)
> - goto cleanup;
> -
> - if (!(all_nodes = virNumaGetHostNodeset()))
> - goto cleanup;
> -
> - if (!(all_nodes_str = virBitmapFormat(all_nodes)))
> - goto cleanup;
> -
> - if (virCgroupGetCpusetMems(cgroup_temp, &mem_mask) < 0 ||
> - virCgroupSetCpusetMems(cgroup_temp, all_nodes_str) < 0)
> - goto cleanup;
> - }
> + if (qemuCgroupEmulatorAllNodesAllow(priv->cgroup, &emulatorCgroup) < 0)
> + goto cleanup;
>
> if (nvcpus > virDomainDefGetVcpus(vm->def)) {
> while ((nextvcpu = virBitmapNextSetBit(vcpumap, nextvcpu)) != -1) {
> @@ -4909,17 +4891,7 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
> ret = 0;
>
> cleanup:
> - if (mem_mask) {
> - err = virSaveLastError();
> - virCgroupSetCpusetMems(cgroup_temp, mem_mask);
> - virSetError(err);
> - virFreeError(err);
> - VIR_FREE(mem_mask);
> - }
> -
> - VIR_FREE(all_nodes_str);
> - virBitmapFree(all_nodes);
> - virCgroupFree(&cgroup_temp);
> + qemuCgrouEmulatorAllNodesRestore(emulatorCgroup);
> virBitmapFree(vcpumap);
>
> return ret;
>
--
Mit freundlichen Grüßen/Kind regards
Boris Fiuczynski
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martina Köderitz
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
More information about the libvir-list
mailing list