create a new cgroup and move all hypervisor threads to the new cgroup.
And then we can do the other things:
1. limit only vcpu usage rather than the whole qemu
2. limit for hypervisor threads(include vhost-net threads)
---
src/qemu/qemu_cgroup.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_cgroup.h | 2 +
src/qemu/qemu_process.c | 4 +++
3 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index f8f375f..e69ef5b 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -573,6 +573,63 @@ cleanup:
return -1;
}
+int qemuSetupCgroupForHypervisor(struct qemud_driver *driver,
+ virDomainObjPtr vm)
+{
+ virCgroupPtr cgroup = NULL;
+ virCgroupPtr cgroup_hypervisor = NULL;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ int rc;
+
+ if (driver->cgroup == NULL)
+ return 0; /* Not supported, so claim success */
+
+ rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to find cgroup for %s"),
+ vm->def->name);
+ goto cleanup;
+ }
+
+ if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
+ /* If we does not know VCPU<->PID mapping or all vcpu runs in the same
+ * thread, we cannot control each vcpu.
+ */
+ virCgroupFree(&cgroup);
+ return 0;
+ }
+
+ rc = virCgroupForHypervisor(cgroup, &cgroup_hypervisor, 1);
+ if (rc < 0) {
+ virReportSystemError(-rc,
+ _("Unable to create hypervisor cgroup for %s"),
+ vm->def->name);
+ goto cleanup;
+ }
+
+ rc = virCgroupMoveTask(cgroup, cgroup_hypervisor);
+ if (rc < 0) {
+ virReportSystemError(-rc,
+ _("Unable to move taks from domain cgroup to "
+ "hypervisor cgroup for %s"),
+ vm->def->name);
+ goto cleanup;
+ }
+
+ virCgroupFree(&cgroup_hypervisor);
+ virCgroupFree(&cgroup);
+ return 0;
+
+cleanup:
+ virCgroupFree(&cgroup_hypervisor);
+ if (cgroup) {
+ virCgroupRemove(cgroup);
+ virCgroupFree(&cgroup);
+ }
+
+ return -1;
+}
int qemuRemoveCgroup(struct qemud_driver *driver,
virDomainObjPtr vm,
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
index c1023b3..cf0d383 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -54,6 +54,8 @@ int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup,
unsigned long long period,
long long quota);
int qemuSetupCgroupForVcpu(struct qemud_driver *driver, virDomainObjPtr vm);
+int qemuSetupCgroupForHypervisor(struct qemud_driver *driver,
+ virDomainObjPtr vm);
int qemuRemoveCgroup(struct qemud_driver *driver,
virDomainObjPtr vm,
int quiet);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 58ba5bf..31c2c30 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3674,6 +3674,10 @@ int qemuProcessStart(virConnectPtr conn,
if (qemuSetupCgroupForVcpu(driver, vm) < 0)
goto cleanup;
+ VIR_DEBUG("Setting cgroup for hypervisor(if required)");
+ if (qemuSetupCgroupForHypervisor(driver, vm) < 0)
+ goto cleanup;
+
VIR_DEBUG("Setting VCPU affinities");
if (qemuProcessSetVcpuAffinites(conn, vm) < 0)
goto cleanup;
--
1.7.3.1