[libvirt] [PATCHv2 5/9] create a new cgroup and move all hypervisor threads to the new cgroup

Hu Tao hutao at cn.fujitsu.com
Tue Jun 26 10:15:42 UTC 2012


From: Wen Congyang <wency at cn.fujitsu.com>

create a new cgroup and move all hypervisor threads to the new cgroup.
And then we can limit cpu bandwidth 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 13163b6..021f489 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -556,6 +556,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 780b4a0..63cb378 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -54,6 +54,8 @@ int qemuSetupCgroupCpuBandwidth(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 1df3637..f84314d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3723,6 +3723,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.4.4




More information about the libvir-list mailing list