This patch introduces support of setting emulator's period and quota to limit cpu bandwidth when the vm starts. Also updates XML Schema for new entries and docs. --- docs/formatdomain.html.in | 24 ++++++++++++++++++++++++ docs/schemas/domaincommon.rng | 10 ++++++++++ src/conf/domain_conf.c | 25 +++++++++++++++++++++++-- src/conf/domain_conf.h | 2 ++ src/qemu/qemu_cgroup.c | 11 ++++++++++- 5 files changed, 69 insertions(+), 3 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 81ec2cd..6142f4b 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -388,6 +388,8 @@ <shares>2048</shares> <period>1000000</period> <quota>-1</quota> + <emulator_period>1000000</period> + <emulator_quota>-1</quota> </cputune> ... </domain> @@ -451,6 +453,28 @@ <span class="since">Only QEMU driver support since 0.9.4, LXC since 0.9.10</span> </dd> + + <dt><code>emulator_period</code></dt> + <dd> + The optional <code>emulator_period</code> element specifies the enforcement + interval(unit: microseconds). Within <code>emulator_period</code>, emulator + threads(those excluding vcpus) of the domain will not be allowed to consume + more than <code>emulator_quota</code> worth of runtime. The value should be + in range [1000, 1000000]. A period with value 0 means no value. + <span class="since">Only QEMU driver support since 0.10.0</span> + </dd> + <dt><code>emulator_quota</code></dt> + <dd> + The optional <code>emulator_quota</code> element specifies the maximum + allowed bandwidth(unit: microseconds) for domain's emulator threads(those + excluding vcpus). A domain with <code>emulator_quota</code> as any negative + value indicates that the domain has infinite bandwidth for emulator threads + (those excluding vcpus), which means that it is not bandwidth controlled. + The value should be in range [1000, 18446744073709551] or less than 0. A + quota with value 0 means no value. + <span class="since">Only QEMU driver support since 0.10.0</span> + </dd> + </dl> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index b02ad96..7aa6e47 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -581,6 +581,16 @@ <ref name="cpuquota"/> </element> </optional> + <optional> + <element name="emulator_period"> + <ref name="cpuperiod"/> + </element> + </optional> + <optional> + <element name="emulator_quota"> + <ref name="cpuquota"/> + </element> + </optional> <zeroOrMore> <element name="vcpupin"> <attribute name="vcpu"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index dab9c5d..7bb07b4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8297,6 +8297,14 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, &def->cputune.quota) < 0) def->cputune.quota = 0; + if (virXPathULongLong("string(./cputune/emulator_period[1])", ctxt, + &def->cputune.emulator_period) < 0) + def->cputune.emulator_period = 0; + + if (virXPathLongLong("string(./cputune/emulator_quota[1])", ctxt, + &def->cputune.emulator_quota) < 0) + def->cputune.emulator_quota = 0; + if ((n = virXPathNodeSet("./cputune/vcpupin", ctxt, &nodes)) < 0) { goto error; } @@ -13030,7 +13038,8 @@ virDomainDefFormatInternal(virDomainDefPtr def, if (def->cputune.shares || def->cputune.vcpupin || def->cputune.period || def->cputune.quota || - def->cputune.emulatorpin) + def->cputune.emulatorpin || + def->cputune.emulator_period || def->cputune.emulator_quota) virBufferAddLit(buf, " <cputune>\n"); if (def->cputune.shares) @@ -13042,6 +13051,17 @@ virDomainDefFormatInternal(virDomainDefPtr def, if (def->cputune.quota) virBufferAsprintf(buf, " <quota>%lld</quota>\n", def->cputune.quota); + + if (def->cputune.emulator_period) + virBufferAsprintf(buf, " <emulator_period>%llu" + "</emulator_period>\n", + def->cputune.emulator_period); + + if (def->cputune.emulator_quota) + virBufferAsprintf(buf, " <emulator_quota>%lld" + "</emulator_quota>\n", + def->cputune.emulator_quota); + if (def->cputune.vcpupin) { for (i = 0; i < def->cputune.nvcpupin; i++) { virBufferAsprintf(buf, " <vcpupin vcpu='%u' ", @@ -13080,7 +13100,8 @@ virDomainDefFormatInternal(virDomainDefPtr def, if (def->cputune.shares || def->cputune.vcpupin || def->cputune.period || def->cputune.quota || - def->cputune.emulatorpin) + def->cputune.emulatorpin || + def->cputune.emulator_period || def->cputune.emulator_quota) virBufferAddLit(buf, " </cputune>\n"); if (def->numatune.memory.nodemask || diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index b6bf5a8..089d9bc 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1598,6 +1598,8 @@ struct _virDomainDef { unsigned long shares; unsigned long long period; long long quota; + unsigned long long emulator_period; + long long emulator_quota; int nvcpupin; virDomainVcpuPinDefPtr *vcpupin; virDomainVcpuPinDefPtr emulatorpin; diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 2fb29b5..2237d11 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -564,7 +564,7 @@ int qemuSetupCgroupForVcpu(struct qemud_driver *driver, virDomainObjPtr vm) } if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) { - /* If we does not know VCPU<->PID mapping or all vcpus run in the same + /* If we don't know VCPU<->PID mapping or all vcpu runs in the same * thread, we cannot control each vcpu. */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -631,6 +631,8 @@ int qemuSetupCgroupForEmulator(struct qemud_driver *driver, virCgroupPtr cgroup = NULL; virCgroupPtr cgroup_emulator = NULL; virDomainDefPtr def = vm->def; + unsigned long long period = vm->def->cputune.emulator_period; + long long quota = vm->def->cputune.emulator_quota; int rc, i; if (driver->cgroup == NULL) @@ -672,6 +674,13 @@ int qemuSetupCgroupForEmulator(struct qemud_driver *driver, qemuSetupCgroupEmulatorPin(cgroup_emulator, def->cputune.emulatorpin) < 0) goto cleanup; + if (period || quota) { + if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { + if (qemuSetupCgroupVcpuBW(cgroup_emulator, period, quota) < 0) + goto cleanup; + } + } + virCgroupFree(&cgroup_emulator); virCgroupFree(&cgroup); return 0; -- 1.7.10.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list