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