render / rpms / libvirt

Forked from rpms/libvirt 10 months ago
Clone
6ae9ed
From 341e7b3d6b2e1d1bc9c11aa59ebac376f847da87 Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <341e7b3d6b2e1d1bc9c11aa59ebac376f847da87@dist-git>
6ae9ed
From: Martin Kletzander <mkletzan@redhat.com>
6ae9ed
Date: Wed, 24 Aug 2016 16:10:54 -0400
6ae9ed
Subject: [PATCH] qemu: Add qemuProcessSetupPid() and use it in
6ae9ed
 qemuProcessSetupIOThread()
6ae9ed
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1097930
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1224341
6ae9ed
6ae9ed
Setting up cgroups and other things for all kinds of threads (the
6ae9ed
emulator thread, vCPU threads, I/O threads) was copy-pasted every time
6ae9ed
new thing was added.  Over time each one of those functions changed a
6ae9ed
bit differently.  So create one function that does all that setup and
6ae9ed
start using it, starting with I/O thread setup.  That will shave some
6ae9ed
duplicated code and maybe fix some bugs as well.
6ae9ed
6ae9ed
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
6ae9ed
(cherry picked from commit 71e419bbeb7d7bf6f9be0c2516c320cfb7492ef3)
6ae9ed
---
6ae9ed
 src/qemu/qemu_process.c | 200 +++++++++++++++++++++++++++---------------------
6ae9ed
 1 file changed, 114 insertions(+), 86 deletions(-)
6ae9ed
6ae9ed
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
6ae9ed
index 41e401b..64b1ac9 100644
6ae9ed
--- a/src/qemu/qemu_process.c
6ae9ed
+++ b/src/qemu/qemu_process.c
6ae9ed
@@ -2304,6 +2304,114 @@ qemuProcessSetLinkStates(virQEMUDriverPtr driver,
6ae9ed
 }
6ae9ed
 
6ae9ed
 
6ae9ed
+/**
6ae9ed
+ * qemuProcessSetupPid:
6ae9ed
+ *
6ae9ed
+ * This function sets resource properities (affinity, cgroups,
6ae9ed
+ * scheduler) for any PID associated with a domain.  It should be used
6ae9ed
+ * to set up emulator PIDs as well as vCPU and I/O thread pids to
6ae9ed
+ * ensure they are all handled the same way.
6ae9ed
+ *
6ae9ed
+ * Returns 0 on success, -1 on error.
6ae9ed
+ */
6ae9ed
+static int
6ae9ed
+qemuProcessSetupPid(virDomainObjPtr vm,
6ae9ed
+                    pid_t pid,
6ae9ed
+                    virCgroupThreadName nameval,
6ae9ed
+                    int id,
6ae9ed
+                    virBitmapPtr cpumask,
6ae9ed
+                    unsigned long long period,
6ae9ed
+                    long long quota,
6ae9ed
+                    virDomainThreadSchedParamPtr sched)
6ae9ed
+{
6ae9ed
+    qemuDomainObjPrivatePtr priv = vm->privateData;
6ae9ed
+    virDomainNumatuneMemMode mem_mode;
6ae9ed
+    virCgroupPtr cgroup = NULL;
6ae9ed
+    virBitmapPtr use_cpumask;
6ae9ed
+    char *mem_mask = NULL;
6ae9ed
+    int ret = -1;
6ae9ed
+
6ae9ed
+    if ((period || quota) &&
6ae9ed
+        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
6ae9ed
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6ae9ed
+                       _("cgroup cpu is required for scheduler tuning"));
6ae9ed
+        goto cleanup;
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    /* Infer which cpumask shall be used. */
6ae9ed
+    if (cpumask)
6ae9ed
+        use_cpumask = cpumask;
6ae9ed
+    else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
6ae9ed
+        use_cpumask = priv->autoCpuset;
6ae9ed
+    else
6ae9ed
+        use_cpumask = vm->def->cpumask;
6ae9ed
+
6ae9ed
+    /*
6ae9ed
+     * If CPU cgroup controller is not initialized here, then we need
6ae9ed
+     * neither period nor quota settings.  And if CPUSET controller is
6ae9ed
+     * not initialized either, then there's nothing to do anyway.
6ae9ed
+     */
6ae9ed
+    if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) ||
6ae9ed
+        virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
6ae9ed
+
6ae9ed
+        if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
6ae9ed
+            mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
6ae9ed
+            virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
6ae9ed
+                                                priv->autoNodeset,
6ae9ed
+                                                &mem_mask, -1) < 0)
6ae9ed
+            goto cleanup;
6ae9ed
+
6ae9ed
+        if (virCgroupNewThread(priv->cgroup, nameval, id, true, &cgroup) < 0)
6ae9ed
+            goto cleanup;
6ae9ed
+
6ae9ed
+        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
6ae9ed
+            if (use_cpumask &&
6ae9ed
+                qemuSetupCgroupCpusetCpus(cgroup, use_cpumask) < 0)
6ae9ed
+                goto cleanup;
6ae9ed
+
6ae9ed
+            /*
6ae9ed
+             * Don't setup cpuset.mems for the emulator, they need to
6ae9ed
+             * be set up after initialization in order for kvm
6ae9ed
+             * allocations to succeed.
6ae9ed
+             */
6ae9ed
+            if (nameval != VIR_CGROUP_THREAD_EMULATOR &&
6ae9ed
+                mem_mask && virCgroupSetCpusetMems(cgroup, mem_mask) < 0)
6ae9ed
+                goto cleanup;
6ae9ed
+
6ae9ed
+        }
6ae9ed
+
6ae9ed
+        if ((period || quota) &&
6ae9ed
+            qemuSetupCgroupVcpuBW(cgroup, period, quota) < 0)
6ae9ed
+            goto cleanup;
6ae9ed
+
6ae9ed
+        /* Move the thread to the sub dir */
6ae9ed
+        if (virCgroupAddTask(cgroup, pid) < 0)
6ae9ed
+            goto cleanup;
6ae9ed
+
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    /* Setup legacy affinity. */
6ae9ed
+    if (use_cpumask && virProcessSetAffinity(pid, use_cpumask) < 0)
6ae9ed
+        goto cleanup;
6ae9ed
+
6ae9ed
+    /* Set scheduler type and priority. */
6ae9ed
+    if (sched &&
6ae9ed
+        virProcessSetScheduler(pid, sched->policy, sched->priority) < 0)
6ae9ed
+        goto cleanup;
6ae9ed
+
6ae9ed
+    ret = 0;
6ae9ed
+ cleanup:
6ae9ed
+    VIR_FREE(mem_mask);
6ae9ed
+    if (cgroup) {
6ae9ed
+        if (ret < 0)
6ae9ed
+            virCgroupRemove(cgroup);
6ae9ed
+        virCgroupFree(&cgroup);
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    return ret;
6ae9ed
+}
6ae9ed
+
6ae9ed
+
6ae9ed
 static int
6ae9ed
 qemuProcessSetupEmulator(virDomainObjPtr vm)
6ae9ed
 {
6ae9ed
@@ -4704,98 +4812,18 @@ qemuProcessSetupVcpus(virDomainObjPtr vm)
6ae9ed
 }
6ae9ed
 
6ae9ed
 
6ae9ed
-/**
6ae9ed
- * qemuProcessSetupIOThread:
6ae9ed
- * @vm: domain object
6ae9ed
- * @iothread: iothread data structure to set the data for
6ae9ed
- *
6ae9ed
- * This function sets resource properities (affinity, cgroups, scheduler) for a
6ae9ed
- * IOThread. This function expects that the IOThread is online and the IOThread
6ae9ed
- * pids were correctly detected at the point when it's called.
6ae9ed
- *
6ae9ed
- * Returns 0 on success, -1 on error.
6ae9ed
- */
6ae9ed
 int
6ae9ed
 qemuProcessSetupIOThread(virDomainObjPtr vm,
6ae9ed
                          virDomainIOThreadIDDefPtr iothread)
6ae9ed
 {
6ae9ed
-    qemuDomainObjPrivatePtr priv = vm->privateData;
6ae9ed
-    unsigned long long period = vm->def->cputune.period;
6ae9ed
-    long long quota = vm->def->cputune.quota;
6ae9ed
-    virDomainNumatuneMemMode mem_mode;
6ae9ed
-    char *mem_mask = NULL;
6ae9ed
-    virCgroupPtr cgroup_iothread = NULL;
6ae9ed
-    virBitmapPtr cpumask = NULL;
6ae9ed
-    int ret = -1;
6ae9ed
 
6ae9ed
-    if ((period || quota) &&
6ae9ed
-        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
6ae9ed
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6ae9ed
-                       _("cgroup cpu is required for scheduler tuning"));
6ae9ed
-        return -1;
6ae9ed
-    }
6ae9ed
-
6ae9ed
-    if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) ||
6ae9ed
-        virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
6ae9ed
-        if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
6ae9ed
-            mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
6ae9ed
-            virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
6ae9ed
-                                                priv->autoNodeset,
6ae9ed
-                                                &mem_mask, -1) < 0)
6ae9ed
-            goto cleanup;
6ae9ed
-
6ae9ed
-        if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
6ae9ed
+    return qemuProcessSetupPid(vm, iothread->thread_id,
6ae9ed
+                               VIR_CGROUP_THREAD_IOTHREAD,
6ae9ed
                                iothread->iothread_id,
6ae9ed
-                               true, &cgroup_iothread) < 0)
6ae9ed
-            goto cleanup;
6ae9ed
-    }
6ae9ed
-
6ae9ed
-    if (iothread->cpumask)
6ae9ed
-        cpumask = iothread->cpumask;
6ae9ed
-    else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
6ae9ed
-        cpumask = priv->autoCpuset;
6ae9ed
-    else
6ae9ed
-        cpumask = vm->def->cpumask;
6ae9ed
-
6ae9ed
-    if (period || quota) {
6ae9ed
-        if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
6ae9ed
-            goto cleanup;
6ae9ed
-    }
6ae9ed
-
6ae9ed
-    if (cgroup_iothread) {
6ae9ed
-        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
6ae9ed
-            if (mem_mask &&
6ae9ed
-                virCgroupSetCpusetMems(cgroup_iothread, mem_mask) < 0)
6ae9ed
-                goto cleanup;
6ae9ed
-
6ae9ed
-            if (cpumask &&
6ae9ed
-                qemuSetupCgroupCpusetCpus(cgroup_iothread, cpumask) < 0)
6ae9ed
-                goto cleanup;
6ae9ed
-        }
6ae9ed
-
6ae9ed
-        if (virCgroupAddTask(cgroup_iothread, iothread->thread_id) < 0)
6ae9ed
-            goto cleanup;
6ae9ed
-    }
6ae9ed
-
6ae9ed
-    if (cpumask && virProcessSetAffinity(iothread->thread_id, cpumask) < 0)
6ae9ed
-        goto cleanup;
6ae9ed
-
6ae9ed
-    if (iothread->sched.policy != VIR_PROC_POLICY_NONE &&
6ae9ed
-        virProcessSetScheduler(iothread->thread_id, iothread->sched.policy,
6ae9ed
-                               iothread->sched.priority) < 0)
6ae9ed
-        goto cleanup;
6ae9ed
-
6ae9ed
-    ret = 0;
6ae9ed
-
6ae9ed
- cleanup:
6ae9ed
-    if (cgroup_iothread) {
6ae9ed
-        if (ret < 0)
6ae9ed
-            virCgroupRemove(cgroup_iothread);
6ae9ed
-        virCgroupFree(&cgroup_iothread);
6ae9ed
-    }
6ae9ed
-
6ae9ed
-    VIR_FREE(mem_mask);
6ae9ed
-    return ret;
6ae9ed
+                               iothread->cpumask,
6ae9ed
+                               vm->def->cputune.period,
6ae9ed
+                               vm->def->cputune.quota,
6ae9ed
+                               &iothread->sched);
6ae9ed
 }
6ae9ed
 
6ae9ed
 
6ae9ed
-- 
6ae9ed
2.10.0
6ae9ed