|
|
6ae9ed |
From b858c92c39a76d6a4aedea05b4f9bf801055f824 Mon Sep 17 00:00:00 2001
|
|
|
6ae9ed |
Message-Id: <b858c92c39a76d6a4aedea05b4f9bf801055f824@dist-git>
|
|
|
6ae9ed |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
6ae9ed |
Date: Wed, 7 Sep 2016 16:12:13 +0200
|
|
|
6ae9ed |
Subject: [PATCH] qemu: cgroup: Extract temporary relaxing of cgroup setting
|
|
|
6ae9ed |
for vcpu hotplug
|
|
|
6ae9ed |
|
|
|
6ae9ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1097930
|
|
|
6ae9ed |
|
|
|
6ae9ed |
When hot-adding vcpus qemu needs to allocate some structures in the DMA
|
|
|
6ae9ed |
zone which may be outside of the numa pinning. Extract the code doing
|
|
|
6ae9ed |
this in a set of helpers so that it can be reused.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
(cherry picked from commit eb5dee353479629d8769de0cfe77c59711c70d79)
|
|
|
6ae9ed |
---
|
|
|
6ae9ed |
src/qemu/qemu_cgroup.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
6ae9ed |
src/qemu/qemu_cgroup.h | 11 ++++++
|
|
|
6ae9ed |
src/qemu/qemu_driver.c | 36 +++-----------------
|
|
|
6ae9ed |
3 files changed, 105 insertions(+), 32 deletions(-)
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
|
|
|
6ae9ed |
index 2dca874..e2b5bab 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_cgroup.c
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_cgroup.c
|
|
|
6ae9ed |
@@ -1127,3 +1127,93 @@ qemuRemoveCgroup(virDomainObjPtr vm)
|
|
|
6ae9ed |
|
|
|
6ae9ed |
return virCgroupRemove(priv->cgroup);
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+static void
|
|
|
6ae9ed |
+qemuCgroupEmulatorAllNodesDataFree(qemuCgroupEmulatorAllNodesDataPtr data)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ if (!data)
|
|
|
6ae9ed |
+ return;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ virCgroupFree(&data->emulatorCgroup);
|
|
|
6ae9ed |
+ VIR_FREE(data->emulatorMemMask);
|
|
|
6ae9ed |
+ VIR_FREE(data);
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+/**
|
|
|
6ae9ed |
+ * qemuCgroupEmulatorAllNodesAllow:
|
|
|
6ae9ed |
+ * @cgroup: domain cgroup pointer
|
|
|
6ae9ed |
+ * @retData: filled with structure used to roll back the operation
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * Allows all NUMA nodes for the qemu emulator thread temporarily. This is
|
|
|
6ae9ed |
+ * necessary when hotplugging cpus since it requires memory allocated in the
|
|
|
6ae9ed |
+ * DMA region. Afterwards the operation can be reverted by
|
|
|
6ae9ed |
+ * qemuCgrouEmulatorAllNodesRestore.
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * Returns 0 on success -1 on error
|
|
|
6ae9ed |
+ */
|
|
|
6ae9ed |
+int
|
|
|
6ae9ed |
+qemuCgroupEmulatorAllNodesAllow(virCgroupPtr cgroup,
|
|
|
6ae9ed |
+ qemuCgroupEmulatorAllNodesDataPtr *retData)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ qemuCgroupEmulatorAllNodesDataPtr data = NULL;
|
|
|
6ae9ed |
+ char *all_nodes_str = NULL;
|
|
|
6ae9ed |
+ virBitmapPtr all_nodes = NULL;
|
|
|
6ae9ed |
+ int ret = -1;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!virNumaIsAvailable() ||
|
|
|
6ae9ed |
+ !virCgroupHasController(cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
|
|
|
6ae9ed |
+ return 0;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!(all_nodes = virNumaGetHostNodeset()))
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!(all_nodes_str = virBitmapFormat(all_nodes)))
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (VIR_ALLOC(data) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (virCgroupNewThread(cgroup, VIR_CGROUP_THREAD_EMULATOR, 0,
|
|
|
6ae9ed |
+ false, &data->emulatorCgroup) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (virCgroupGetCpusetMems(data->emulatorCgroup, &data->emulatorMemMask) < 0 ||
|
|
|
6ae9ed |
+ virCgroupSetCpusetMems(data->emulatorCgroup, all_nodes_str) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ VIR_STEAL_PTR(*retData, data);
|
|
|
6ae9ed |
+ ret = 0;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ cleanup:
|
|
|
6ae9ed |
+ VIR_FREE(all_nodes_str);
|
|
|
6ae9ed |
+ virBitmapFree(all_nodes);
|
|
|
6ae9ed |
+ qemuCgroupEmulatorAllNodesDataFree(data);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ return ret;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+/**
|
|
|
6ae9ed |
+ * qemuCgrouEmulatorAllNodesRestore:
|
|
|
6ae9ed |
+ * @data: data structure created by qemuCgroupEmulatorAllNodesAllow
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * Rolls back the setting done by qemuCgroupEmulatorAllNodesAllow and frees the
|
|
|
6ae9ed |
+ * associated data.
|
|
|
6ae9ed |
+ */
|
|
|
6ae9ed |
+void
|
|
|
6ae9ed |
+qemuCgrouEmulatorAllNodesRestore(qemuCgroupEmulatorAllNodesDataPtr data)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ virErrorPtr err;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!data)
|
|
|
6ae9ed |
+ return;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ err = virSaveLastError();
|
|
|
6ae9ed |
+ virCgroupSetCpusetMems(data->emulatorCgroup, data->emulatorMemMask);
|
|
|
6ae9ed |
+ virSetError(err);
|
|
|
6ae9ed |
+ virFreeError(err);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ qemuCgroupEmulatorAllNodesDataFree(data);
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
|
|
|
6ae9ed |
index dc340a1..e6ebae0 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_cgroup.h
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_cgroup.h
|
|
|
6ae9ed |
@@ -57,4 +57,15 @@ int qemuSetupCgroupCpusetCpus(virCgroupPtr cgroup, virBitmapPtr cpumask);
|
|
|
6ae9ed |
int qemuSetupGlobalCpuCgroup(virDomainObjPtr vm);
|
|
|
6ae9ed |
int qemuRemoveCgroup(virDomainObjPtr vm);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+typedef struct _qemuCgroupEmulatorAllNodesData qemuCgroupEmulatorAllNodesData;
|
|
|
6ae9ed |
+typedef qemuCgroupEmulatorAllNodesData *qemuCgroupEmulatorAllNodesDataPtr;
|
|
|
6ae9ed |
+struct _qemuCgroupEmulatorAllNodesData {
|
|
|
6ae9ed |
+ virCgroupPtr emulatorCgroup;
|
|
|
6ae9ed |
+ char *emulatorMemMask;
|
|
|
6ae9ed |
+};
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+int qemuCgroupEmulatorAllNodesAllow(virCgroupPtr cgroup,
|
|
|
6ae9ed |
+ qemuCgroupEmulatorAllNodesDataPtr *data);
|
|
|
6ae9ed |
+void qemuCgrouEmulatorAllNodesRestore(qemuCgroupEmulatorAllNodesDataPtr data);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
#endif /* __QEMU_CGROUP_H__ */
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
6ae9ed |
index 33bfb67..6775327 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_driver.c
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_driver.c
|
|
|
6ae9ed |
@@ -4859,11 +4859,7 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
unsigned int nvcpus)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
6ae9ed |
- virCgroupPtr cgroup_temp = NULL;
|
|
|
6ae9ed |
- char *mem_mask = NULL;
|
|
|
6ae9ed |
- char *all_nodes_str = NULL;
|
|
|
6ae9ed |
- virBitmapPtr all_nodes = NULL;
|
|
|
6ae9ed |
- virErrorPtr err = NULL;
|
|
|
6ae9ed |
+ qemuCgroupEmulatorAllNodesDataPtr emulatorCgroup = NULL;
|
|
|
6ae9ed |
virBitmapPtr vcpumap = NULL;
|
|
|
6ae9ed |
ssize_t nextvcpu = -1;
|
|
|
6ae9ed |
int rc = 0;
|
|
|
6ae9ed |
@@ -4872,22 +4868,8 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
if (!(vcpumap = qemuDomainSelectHotplugVcpuEntities(vm->def, nvcpus)))
|
|
|
6ae9ed |
goto cleanup;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
- if (virNumaIsAvailable() &&
|
|
|
6ae9ed |
- virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
|
|
|
6ae9ed |
- if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_EMULATOR, 0,
|
|
|
6ae9ed |
- false, &cgroup_temp) < 0)
|
|
|
6ae9ed |
- goto cleanup;
|
|
|
6ae9ed |
-
|
|
|
6ae9ed |
- if (!(all_nodes = virNumaGetHostNodeset()))
|
|
|
6ae9ed |
- goto cleanup;
|
|
|
6ae9ed |
-
|
|
|
6ae9ed |
- if (!(all_nodes_str = virBitmapFormat(all_nodes)))
|
|
|
6ae9ed |
- goto cleanup;
|
|
|
6ae9ed |
-
|
|
|
6ae9ed |
- if (virCgroupGetCpusetMems(cgroup_temp, &mem_mask) < 0 ||
|
|
|
6ae9ed |
- virCgroupSetCpusetMems(cgroup_temp, all_nodes_str) < 0)
|
|
|
6ae9ed |
- goto cleanup;
|
|
|
6ae9ed |
- }
|
|
|
6ae9ed |
+ if (qemuCgroupEmulatorAllNodesAllow(priv->cgroup, &emulatorCgroup) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
if (nvcpus > virDomainDefGetVcpus(vm->def)) {
|
|
|
6ae9ed |
while ((nextvcpu = virBitmapNextSetBit(vcpumap, nextvcpu)) != -1) {
|
|
|
6ae9ed |
@@ -4915,17 +4897,7 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
ret = 0;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
cleanup:
|
|
|
6ae9ed |
- if (mem_mask) {
|
|
|
6ae9ed |
- err = virSaveLastError();
|
|
|
6ae9ed |
- virCgroupSetCpusetMems(cgroup_temp, mem_mask);
|
|
|
6ae9ed |
- virSetError(err);
|
|
|
6ae9ed |
- virFreeError(err);
|
|
|
6ae9ed |
- VIR_FREE(mem_mask);
|
|
|
6ae9ed |
- }
|
|
|
6ae9ed |
-
|
|
|
6ae9ed |
- VIR_FREE(all_nodes_str);
|
|
|
6ae9ed |
- virBitmapFree(all_nodes);
|
|
|
6ae9ed |
- virCgroupFree(&cgroup_temp);
|
|
|
6ae9ed |
+ qemuCgrouEmulatorAllNodesRestore(emulatorCgroup);
|
|
|
6ae9ed |
virBitmapFree(vcpumap);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
return ret;
|
|
|
6ae9ed |
--
|
|
|
6ae9ed |
2.10.0
|
|
|
6ae9ed |
|