[libvirt] [PATCH v2.1 19/21] qemu: introduce period/quota tuning for emulator
Daniel Veillard
veillard at redhat.com
Wed Aug 22 09:02:03 UTC 2012
On Tue, Aug 21, 2012 at 05:18:42PM +0800, Hu Tao wrote:
> 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;
ACK, looks fine,
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list