From 6a60677f21bd3ef90603e25d9c609c3f569918c3 Mon Sep 17 00:00:00 2001 Message-Id: <6a60677f21bd3ef90603e25d9c609c3f569918c3@dist-git> From: John Ferlan 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 --- 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