9119d9
From c6bfaa39bd6a2d1bfd0e608b38afa39a698c809b Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <c6bfaa39bd6a2d1bfd0e608b38afa39a698c809b@dist-git>
9119d9
From: John Ferlan <jferlan@redhat.com>
9119d9
Date: Thu, 18 Sep 2014 09:29:53 -0400
9119d9
Subject: [PATCH] qemu_cgroup: Introduce cgroup functions for IOThreads
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1101574
9119d9
9119d9
In order to support cpuset setting, introduce qemuSetupCgroupIOThreadsPin
9119d9
and qemuSetupCgroupForIOThreads to mimic the existing Vcpu API's.
9119d9
9119d9
These will support having an 'iotrhreadpin' element in the 'cpuset' in
9119d9
order to pin named IOThreads to specific CPU's. The IOThread pin names
9119d9
will follow the IOThread naming scheme starting at 1 (eg "iothread1")
9119d9
up through an including the def->iothreads value.
9119d9
9119d9
(cherry picked from commit 5f6ad32c733a3bd158938aecabb0508a434ece95)
9119d9
9119d9
NOTE: Requires commit 938fb12fad6d15c9fdb73f998c4e0ec1e278721f in order
9119d9
      to build - should be two patches later
9119d9
9119d9
Signed-off-by: John Ferlan <jferlan@redhat.com>
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/qemu/qemu_cgroup.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++
9119d9
 src/qemu/qemu_cgroup.h |   5 +++
9119d9
 2 files changed, 109 insertions(+)
9119d9
9119d9
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
9119d9
index 43d14d4..c1d89bb 100644
9119d9
--- a/src/qemu/qemu_cgroup.c
9119d9
+++ b/src/qemu/qemu_cgroup.c
9119d9
@@ -903,6 +903,23 @@ qemuSetupCgroupVcpuPin(virCgroupPtr cgroup,
9119d9
 }
9119d9
 
9119d9
 int
9119d9
+qemuSetupCgroupIOThreadsPin(virCgroupPtr cgroup,
9119d9
+                            virDomainVcpuPinDefPtr *iothreadspin,
9119d9
+                            int niothreadspin,
9119d9
+                            int iothreadid)
9119d9
+{
9119d9
+    size_t i;
9119d9
+
9119d9
+    for (i = 0; i < niothreadspin; i++) {
9119d9
+        if (iothreadid == iothreadspin[i]->vcpuid) {
9119d9
+            return qemuSetupCgroupEmulatorPin(cgroup, iothreadspin[i]->cpumask);
9119d9
+        }
9119d9
+    }
9119d9
+
9119d9
+    return -1;
9119d9
+}
9119d9
+
9119d9
+int
9119d9
 qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup,
9119d9
                            virBitmapPtr cpumask)
9119d9
 {
9119d9
@@ -1083,6 +1100,93 @@ qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
9119d9
 }
9119d9
 
9119d9
 int
9119d9
+qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
9119d9
+{
9119d9
+    virCgroupPtr cgroup_iothread = NULL;
9119d9
+    qemuDomainObjPrivatePtr priv = vm->privateData;
9119d9
+    virDomainDefPtr def = vm->def;
9119d9
+    size_t i, j;
9119d9
+    unsigned long long period = vm->def->cputune.period;
9119d9
+    long long quota = vm->def->cputune.quota;
9119d9
+
9119d9
+    if ((period || quota) &&
9119d9
+        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
9119d9
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
9119d9
+                       _("cgroup cpu is required for scheduler tuning"));
9119d9
+        return -1;
9119d9
+    }
9119d9
+
9119d9
+    /*
9119d9
+     * If CPU cgroup controller is not initialized here, then we need
9119d9
+     * neither period nor quota settings.  And if CPUSET controller is
9119d9
+     * not initialized either, then there's nothing to do anyway.
9119d9
+     */
9119d9
+    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) &&
9119d9
+        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
9119d9
+        return 0;
9119d9
+
9119d9
+    /* We are trying to setup cgroups for CPU pinning, which can also be done
9119d9
+     * with virProcessSetAffinity, thus the lack of cgroups is not fatal here.
9119d9
+     */
9119d9
+    if (priv->cgroup == NULL)
9119d9
+        return 0;
9119d9
+
9119d9
+    if (priv->niothreadpids == 0) {
9119d9
+        VIR_WARN("Unable to get iothreads' pids.");
9119d9
+        return 0;
9119d9
+    }
9119d9
+
9119d9
+    for (i = 0; i < priv->niothreadpids; i++) {
9119d9
+        /* IOThreads are numbered 1..n, although the array is 0..n-1,
9119d9
+         * so we will account for that here
9119d9
+         */
9119d9
+        if (virCgroupNewIOThread(priv->cgroup, i+1, true, &cgroup_iothread) < 0)
9119d9
+            goto cleanup;
9119d9
+
9119d9
+        /* move the thread for iothread to sub dir */
9119d9
+        if (virCgroupAddTask(cgroup_iothread, priv->iothreadpids[i]) < 0)
9119d9
+            goto cleanup;
9119d9
+
9119d9
+        if (period || quota) {
9119d9
+            if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
9119d9
+                goto cleanup;
9119d9
+        }
9119d9
+
9119d9
+        /* Set iothreadpin in cgroup if iothreadpin xml is provided */
9119d9
+        if (virCgroupHasController(priv->cgroup,
9119d9
+                                   VIR_CGROUP_CONTROLLER_CPUSET)) {
9119d9
+            /* find the right CPU to pin, otherwise
9119d9
+             * qemuSetupCgroupIOThreadsPin will fail. */
9119d9
+            for (j = 0; j < def->cputune.niothreadspin; j++) {
9119d9
+                /* IOThreads are numbered/named 1..n */
9119d9
+                if (def->cputune.iothreadspin[j]->vcpuid != i+1)
9119d9
+                    continue;
9119d9
+
9119d9
+                if (qemuSetupCgroupIOThreadsPin(cgroup_iothread,
9119d9
+                                                def->cputune.iothreadspin,
9119d9
+                                                def->cputune.niothreadspin,
9119d9
+                                                i+1) < 0)
9119d9
+                    goto cleanup;
9119d9
+
9119d9
+                break;
9119d9
+            }
9119d9
+        }
9119d9
+
9119d9
+        virCgroupFree(&cgroup_iothread);
9119d9
+    }
9119d9
+
9119d9
+    return 0;
9119d9
+
9119d9
+ cleanup:
9119d9
+    if (cgroup_iothread) {
9119d9
+        virCgroupRemove(cgroup_iothread);
9119d9
+        virCgroupFree(&cgroup_iothread);
9119d9
+    }
9119d9
+
9119d9
+    return -1;
9119d9
+}
9119d9
+
9119d9
+int
9119d9
 qemuRemoveCgroup(virDomainObjPtr vm)
9119d9
 {
9119d9
     qemuDomainObjPrivatePtr priv = vm->privateData;
9119d9
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
9119d9
index 7394969..8a2c723 100644
9119d9
--- a/src/qemu/qemu_cgroup.h
9119d9
+++ b/src/qemu/qemu_cgroup.h
9119d9
@@ -57,7 +57,12 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup,
9119d9
                            int nvcpupin,
9119d9
                            int vcpuid);
9119d9
 int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, virBitmapPtr cpumask);
9119d9
+int qemuSetupCgroupIOThreadsPin(virCgroupPtr cgroup,
9119d9
+                                virDomainVcpuPinDefPtr *iothreadspin,
9119d9
+                                int niothreadspin,
9119d9
+                                int iothreadid);
9119d9
 int qemuSetupCgroupForVcpu(virDomainObjPtr vm);
9119d9
+int qemuSetupCgroupForIOThreads(virDomainObjPtr vm);
9119d9
 int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
9119d9
                                virDomainObjPtr vm,
9119d9
                                virBitmapPtr nodemask);
9119d9
-- 
9119d9
2.1.0
9119d9