]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: iothread: Aggregate code to set IOThread tuning
authorPeter Krempa <pkrempa@redhat.com>
Thu, 14 Jan 2016 09:38:02 +0000 (10:38 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 8 Feb 2016 16:05:00 +0000 (17:05 +0100)
Rather than iterating 3 times for various settings this function
aggregates all the code into single place. One of the other advantages
is that it can then be reused for properly setting IOThread info on
hotplug.

src/qemu/qemu_cgroup.c
src/qemu/qemu_cgroup.h
src/qemu/qemu_process.c
src/qemu/qemu_process.h

index f3a9b5ccd203badfbf0b57fa096d3f6bb42c529d..4b5cf36cbec510ee21e12b8c78b174233f4e706e 100644 (file)
@@ -1084,99 +1084,6 @@ qemuSetupCgroupForEmulator(virDomainObjPtr vm)
     return -1;
 }
 
-int
-qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
-{
-    virCgroupPtr cgroup_iothread = NULL;
-    qemuDomainObjPrivatePtr priv = vm->privateData;
-    virDomainDefPtr def = vm->def;
-    size_t i;
-    unsigned long long period = vm->def->cputune.period;
-    long long quota = vm->def->cputune.quota;
-    char *mem_mask = NULL;
-    virDomainNumatuneMemMode mem_mode;
-
-    if (def->niothreadids == 0)
-        return 0;
-
-    if ((period || quota) &&
-        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("cgroup cpu is required for scheduler tuning"));
-        return -1;
-    }
-
-    /*
-     * If CPU cgroup controller is not initialized here, then we need
-     * neither period nor quota settings.  And if CPUSET controller is
-     * not initialized either, then there's nothing to do anyway.
-     */
-    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) &&
-        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
-        return 0;
-
-    if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
-        mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
-        virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
-                                            priv->autoNodeset,
-                                            &mem_mask, -1) < 0)
-        goto cleanup;
-
-    for (i = 0; i < def->niothreadids; i++) {
-        /* IOThreads are numbered 1..n, although the array is 0..n-1,
-         * so we will account for that here
-         */
-        if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
-                               def->iothreadids[i]->iothread_id,
-                               true, &cgroup_iothread) < 0)
-            goto cleanup;
-
-        if (period || quota) {
-            if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
-                goto cleanup;
-        }
-
-        /* Set iothreadpin in cgroup if iothreadpin xml is provided */
-        if (virCgroupHasController(priv->cgroup,
-                                   VIR_CGROUP_CONTROLLER_CPUSET)) {
-            virBitmapPtr cpumask = NULL;
-
-            if (mem_mask &&
-                virCgroupSetCpusetMems(cgroup_iothread, mem_mask) < 0)
-                goto cleanup;
-
-            if (def->iothreadids[i]->cpumask)
-                cpumask = def->iothreadids[i]->cpumask;
-            else if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
-                cpumask = priv->autoCpuset;
-            else
-                cpumask = def->cpumask;
-
-            if (cpumask &&
-                qemuSetupCgroupCpusetCpus(cgroup_iothread, cpumask) < 0)
-                goto cleanup;
-        }
-
-        /* move the thread for iothread to sub dir */
-        if (virCgroupAddTask(cgroup_iothread,
-                             def->iothreadids[i]->thread_id) < 0)
-            goto cleanup;
-
-        virCgroupFree(&cgroup_iothread);
-    }
-    VIR_FREE(mem_mask);
-
-    return 0;
-
- cleanup:
-    if (cgroup_iothread) {
-        virCgroupRemove(cgroup_iothread);
-        virCgroupFree(&cgroup_iothread);
-    }
-    VIR_FREE(mem_mask);
-
-    return -1;
-}
 
 int
 qemuRemoveCgroup(virDomainObjPtr vm)
index 69d1202755a576614912df187084bc52887cde02..021bfe69a3010a219c7bd0f6bb172b1317fd92b9 100644 (file)
@@ -53,7 +53,6 @@ int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup,
                           unsigned long long period,
                           long long quota);
 int qemuSetupCgroupCpusetCpus(virCgroupPtr cgroup, virBitmapPtr cpumask);
-int qemuSetupCgroupForIOThreads(virDomainObjPtr vm);
 int qemuSetupCgroupForEmulator(virDomainObjPtr vm);
 int qemuRemoveCgroup(virDomainObjPtr vm);
 int qemuAddToCgroup(virDomainObjPtr vm);
index 396b03cea7b5d73c1e6ba8ec2fb830e806a188ab..2523d1d73a902d99c03eae7d5a0ab813f997257d 100644 (file)
@@ -2208,47 +2208,6 @@ qemuProcessSetEmulatorAffinity(virDomainObjPtr vm)
     return ret;
 }
 
-/* Set CPU affinities for IOThreads threads. */
-static int
-qemuProcessSetIOThreadsAffinity(virDomainObjPtr vm)
-{
-    virDomainDefPtr def = vm->def;
-    size_t i;
-    int ret = -1;
-
-    for (i = 0; i < def->niothreadids; i++) {
-        /* set affinity only for existing iothreads */
-        if (!def->iothreadids[i]->cpumask)
-            continue;
-
-        if (virProcessSetAffinity(def->iothreadids[i]->thread_id,
-                                  def->iothreadids[i]->cpumask) < 0)
-            goto cleanup;
-    }
-    ret = 0;
-
- cleanup:
-    return ret;
-}
-
-static int
-qemuProcessSetSchedulers(virDomainObjPtr vm)
-{
-    size_t i = 0;
-
-    for (i = 0; i < vm->def->niothreadids; i++) {
-        virDomainIOThreadIDDefPtr info = vm->def->iothreadids[i];
-
-        if (info->sched.policy == VIR_PROC_POLICY_NONE)
-            continue;
-
-        if (virProcessSetScheduler(info->thread_id, info->sched.policy,
-                                   info->sched.priority) < 0)
-            return -1;
-    }
-
-    return 0;
-}
 
 static int
 qemuProcessInitPasswords(virConnectPtr conn,
@@ -4575,6 +4534,117 @@ qemuProcessSetupVcpus(virDomainObjPtr vm)
 }
 
 
+/**
+ * qemuProcessSetupIOThread:
+ * @vm: domain object
+ * @iothread: iothread data structure to set the data for
+ *
+ * This function sets resource properities (affinity, cgroups, scheduler) for a
+ * IOThread. This function expects that the IOThread is online and the IOThread
+ * pids were correctly detected at the point when it's called.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int
+qemuProcessSetupIOThread(virDomainObjPtr vm,
+                         virDomainIOThreadIDDefPtr iothread)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    unsigned long long period = vm->def->cputune.period;
+    long long quota = vm->def->cputune.quota;
+    virDomainNumatuneMemMode mem_mode;
+    char *mem_mask = NULL;
+    virCgroupPtr cgroup_iothread = NULL;
+    virBitmapPtr cpumask = NULL;
+    int ret = -1;
+
+    if ((period || quota) &&
+        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("cgroup cpu is required for scheduler tuning"));
+        return -1;
+    }
+
+    if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) ||
+        virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
+        if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
+            mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
+            virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
+                                                priv->autoNodeset,
+                                                &mem_mask, -1) < 0)
+            goto cleanup;
+
+        if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
+                               iothread->iothread_id,
+                               true, &cgroup_iothread) < 0)
+            goto cleanup;
+    }
+
+    if (iothread->cpumask)
+        cpumask = iothread->cpumask;
+    else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
+        cpumask = priv->autoCpuset;
+    else
+        cpumask = vm->def->cpumask;
+
+    if (period || quota) {
+        if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
+            goto cleanup;
+    }
+
+    if (cgroup_iothread) {
+        if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
+            if (mem_mask &&
+                virCgroupSetCpusetMems(cgroup_iothread, mem_mask) < 0)
+                goto cleanup;
+
+            if (cpumask &&
+                qemuSetupCgroupCpusetCpus(cgroup_iothread, cpumask) < 0)
+                goto cleanup;
+        }
+
+        if (virCgroupAddTask(cgroup_iothread, iothread->thread_id) < 0)
+            goto cleanup;
+    }
+
+    if (cpumask && virProcessSetAffinity(iothread->thread_id, cpumask) < 0)
+        goto cleanup;
+
+    if (iothread->sched.policy != VIR_PROC_POLICY_NONE &&
+        virProcessSetScheduler(iothread->thread_id, iothread->sched.policy,
+                               iothread->sched.priority) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    if (cgroup_iothread) {
+        if (ret < 0)
+            virCgroupRemove(cgroup_iothread);
+        virCgroupFree(&cgroup_iothread);
+    }
+
+    VIR_FREE(mem_mask);
+    return ret;
+}
+
+
+static int
+qemuProcessSetupIOThreads(virDomainObjPtr vm)
+{
+    size_t i;
+
+    for (i = 0; i < vm->def->niothreadids; i++) {
+        virDomainIOThreadIDDefPtr info = vm->def->iothreadids[i];
+
+        if (qemuProcessSetupIOThread(vm, info) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+
 /**
  * qemuProcessLaunch:
  *
@@ -5043,16 +5113,8 @@ qemuProcessLaunch(virConnectPtr conn,
     if (qemuProcessSetupVcpus(vm) < 0)
         goto cleanup;
 
-    VIR_DEBUG("Setting cgroup for each IOThread (if required)");
-    if (qemuSetupCgroupForIOThreads(vm) < 0)
-        goto cleanup;
-
-    VIR_DEBUG("Setting affinity of IOThread threads");
-    if (qemuProcessSetIOThreadsAffinity(vm) < 0)
-        goto cleanup;
-
-    VIR_DEBUG("Setting scheduler parameters");
-    if (qemuProcessSetSchedulers(vm) < 0)
+    VIR_DEBUG("Setting IOThread tuning/settings");
+    if (qemuProcessSetupIOThreads(vm) < 0)
         goto cleanup;
 
     VIR_DEBUG("Setting any required VM passwords");
index 7de9b89131c5a16b341c64559b95ef36562e8589..ad8041085e910060764cb95db7a87fe1ba633ad6 100644 (file)
@@ -163,5 +163,7 @@ int qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm);
 
 int qemuProcessSetupVcpu(virDomainObjPtr vm,
                          unsigned int vcpuid);
+int qemuProcessSetupIOThread(virDomainObjPtr vm,
+                             virDomainIOThreadIDDefPtr iothread);
 
 #endif /* __QEMU_PROCESS_H__ */