Blob Blame History Raw
From 6a60677f21bd3ef90603e25d9c609c3f569918c3 Mon Sep 17 00:00:00 2001
Message-Id: <6a60677f21bd3ef90603e25d9c609c3f569918c3@dist-git>
From: John Ferlan <jferlan@redhat.com>
Date: Tue, 6 Sep 2016 16:43:14 -0400
Subject: [PATCH] qemu: Add support to get/set IOThread period and quota cgroup
 values

https://bugzilla.redhat.com/show_bug.cgi?id=1356937

Add support for IOThread quota/bandwidth and period parameters for non
session mode. If in session mode, then error out.  Uses all the same
places where {vcpu|emulator|global}_{period|quota} are adjusted and
adds the iothread values.

(cherry picked from commit e4e4d17c9c2828b3a7d2909295e724c57e60a334)
Signed-off-by: John Ferlan <jferlan@redhat.com>
---
 src/qemu/qemu_command.c |   3 +-
 src/qemu/qemu_driver.c  | 127 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/qemu/qemu_process.c |   4 +-
 3 files changed, 129 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e292f48..de121c5 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9306,7 +9306,8 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver,
         if (def->cputune.sharesSpecified || def->cputune.period ||
             def->cputune.quota || def->cputune.global_period ||
             def->cputune.global_quota || def->cputune.emulator_period ||
-            def->cputune.emulator_quota) {
+            def->cputune.emulator_quota || def->cputune.iothread_period ||
+            def->cputune.iothread_quota) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("CPU tuning is not available in session mode"));
             return -1;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8081417..33bfb67 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8705,7 +8705,7 @@ static char *qemuDomainGetSchedulerType(virDomainPtr dom,
     /* Domain not running, thus no cgroups - return defaults */
     if (!virDomainObjIsActive(vm)) {
         if (nparams)
-            *nparams = 7;
+            *nparams = 9;
         ignore_value(VIR_STRDUP(ret, "posix"));
         goto cleanup;
     }
@@ -8718,7 +8718,7 @@ static char *qemuDomainGetSchedulerType(virDomainPtr dom,
 
     if (nparams) {
         if (virCgroupSupportsCpuBW(priv->cgroup))
-            *nparams = 7;
+            *nparams = 9;
         else
             *nparams = 1;
     }
@@ -9939,6 +9939,40 @@ qemuSetEmulatorBandwidthLive(virCgroupPtr cgroup,
     return -1;
 }
 
+
+static int
+qemuSetIOThreadsBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
+                       unsigned long long period, long long quota)
+{
+    size_t i;
+    virCgroupPtr cgroup_iothread = NULL;
+
+    if (period == 0 && quota == 0)
+        return 0;
+
+    if (!vm->def->niothreadids)
+        return 0;
+
+    for (i = 0; i < vm->def->niothreadids; i++) {
+        if (virCgroupNewThread(cgroup, VIR_CGROUP_THREAD_IOTHREAD,
+                               vm->def->iothreadids[i]->iothread_id,
+                               false, &cgroup_iothread) < 0)
+            goto cleanup;
+
+        if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
+            goto cleanup;
+
+        virCgroupFree(&cgroup_iothread);
+    }
+
+    return 0;
+
+ cleanup:
+    virCgroupFree(&cgroup_iothread);
+    return -1;
+}
+
+
 #define SCHED_RANGE_CHECK(VAR, NAME, MIN, MAX)                              \
     if (((VAR) > 0 && (VAR) < (MIN)) || (VAR) > (MAX)) {                    \
         virReportError(VIR_ERR_INVALID_ARG,                                 \
@@ -9989,6 +10023,10 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
                                VIR_TYPED_PARAM_ULLONG,
                                VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA,
                                VIR_TYPED_PARAM_LLONG,
+                               VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD,
+                               VIR_TYPED_PARAM_ULLONG,
+                               VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA,
+                               VIR_TYPED_PARAM_LLONG,
                                NULL) < 0)
         return -1;
 
@@ -10181,6 +10219,46 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
 
             if (persistentDef)
                 persistentDefCopy->cputune.emulator_quota = value_l;
+
+        } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD)) {
+            SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD,
+                              QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD);
+
+            if (def && value_ul) {
+                if ((rc = qemuSetIOThreadsBWLive(vm, priv->cgroup, value_ul, 0)))
+                    goto endjob;
+
+                def->cputune.iothread_period = value_ul;
+
+                if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+                                            &eventMaxNparams,
+                                            VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_PERIOD,
+                                            value_ul) < 0)
+                    goto endjob;
+            }
+
+            if (persistentDef)
+                persistentDefCopy->cputune.iothread_period = params[i].value.ul;
+
+        } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA)) {
+            SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA,
+                              QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA);
+
+            if (def && value_l) {
+                if ((rc = qemuSetIOThreadsBWLive(vm, priv->cgroup, 0, value_l)))
+                    goto endjob;
+
+                def->cputune.iothread_quota = value_l;
+
+                if (virTypedParamsAddLLong(&eventParams, &eventNparams,
+                                           &eventMaxNparams,
+                                           VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_QUOTA,
+                                           value_l) < 0)
+                    goto endjob;
+            }
+
+            if (persistentDef)
+                persistentDefCopy->cputune.iothread_quota = value_l;
         }
     }
 
@@ -10304,6 +10382,43 @@ qemuGetEmulatorBandwidthLive(virCgroupPtr cgroup,
 }
 
 static int
+qemuGetIOThreadsBWLive(virDomainObjPtr vm,
+                       unsigned long long *period, long long *quota)
+{
+    virCgroupPtr cgroup_iothread = NULL;
+    qemuDomainObjPrivatePtr priv = NULL;
+    int rc;
+    int ret = -1;
+
+    priv = vm->privateData;
+    if (!vm->def->niothreadids) {
+        /* We do not create sub dir for each iothread */
+        if ((rc = qemuGetVcpuBWLive(priv->cgroup, period, quota)) < 0)
+            goto cleanup;
+
+        goto out;
+    }
+
+    /* get period and quota for the "first" IOThread */
+    if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
+                           vm->def->iothreadids[0]->iothread_id,
+                           false, &cgroup_iothread) < 0)
+        goto cleanup;
+
+    rc = qemuGetVcpuBWLive(cgroup_iothread, period, quota);
+    if (rc < 0)
+        goto cleanup;
+
+ out:
+    ret = 0;
+
+ cleanup:
+    virCgroupFree(&cgroup_iothread);
+    return ret;
+}
+
+
+static int
 qemuGetGlobalBWLive(virCgroupPtr cgroup, unsigned long long *period,
                     long long *quota)
 {
@@ -10378,6 +10493,11 @@ qemuDomainGetSchedulerParametersFlags(virDomainPtr dom,
                 qemuGetGlobalBWLive(priv->cgroup, &data.global_period,
                                     &data.global_quota) < 0)
                 goto cleanup;
+
+            if (maxparams > 7 &&
+                qemuGetIOThreadsBWLive(vm, &data.iothread_period,
+                                       &data.iothread_quota) < 0)
+                goto cleanup;
         } else {
             cpu_bw_status = false;
         }
@@ -10402,6 +10522,9 @@ qemuDomainGetSchedulerParametersFlags(virDomainPtr dom,
 
         QEMU_SCHED_ASSIGN(global_period, GLOBAL_PERIOD, ULLONG);
         QEMU_SCHED_ASSIGN(global_quota, GLOBAL_QUOTA, LLONG);
+
+        QEMU_SCHED_ASSIGN(iothread_period, IOTHREAD_PERIOD, ULLONG);
+        QEMU_SCHED_ASSIGN(iothread_quota, IOTHREAD_QUOTA, LLONG);
     }
 
 #undef QEMU_SCHED_ASSIGN
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2eac422..9583506 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4697,8 +4697,8 @@ qemuProcessSetupIOThread(virDomainObjPtr vm,
                                VIR_CGROUP_THREAD_IOTHREAD,
                                iothread->iothread_id,
                                iothread->cpumask,
-                               vm->def->cputune.period,
-                               vm->def->cputune.quota,
+                               vm->def->cputune.iothread_period,
+                               vm->def->cputune.iothread_quota,
                                &iothread->sched);
 }
 
-- 
2.10.0