[libvirt] [PATCH v2.1 19/21] qemu: introduce period/quota tuning for emulator

Hu Tao hutao at cn.fujitsu.com
Tue Aug 21 09:18:42 UTC 2012


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




More information about the libvir-list mailing list