[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