]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: introduce period/quota tuning for emulator
authorHu Tao <hutao@cn.fujitsu.com>
Tue, 21 Aug 2012 09:18:42 +0000 (17:18 +0800)
committerDaniel Veillard <veillard@redhat.com>
Wed, 22 Aug 2012 08:52:22 +0000 (16:52 +0800)
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
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_cgroup.c

index 42df928a301273afa39ee4327b8d4690ad197b45..5d8f66957a8ff0f5e1f1315595ebb5990d86f97b 100644 (file)
     &lt;shares&gt;2048&lt;/shares&gt;
     &lt;period&gt;1000000&lt;/period&gt;
     &lt;quota&gt;-1&lt;/quota&gt;
+    &lt;emulator_period&gt;1000000&lt;/period&gt;
+    &lt;emulator_quota&gt;-1&lt;/quota&gt;
   &lt;/cputune&gt;
   ...
 &lt;/domain&gt;
         <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>
 
 
index f4005c51e26d75b736c351154b0c75fc07ec2f73..145caf78d82805cb2a936edba9972afd2f5f0591 100644 (file)
               <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">
index 9e97301374c323781bf898570e2bdd6c50a93383..724220576add7fac3a527aa4b81afb398cf4359e 100644 (file)
@@ -8344,6 +8344,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;
     }
@@ -13102,7 +13110,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)
@@ -13114,6 +13123,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' ",
@@ -13152,7 +13172,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 ||
index 5a02323ea776a03285bcc5169e3d97008a118b8c..0c3824ec7f15d3f4568f82f0db6a1744bf52e2b5 100644 (file)
@@ -1614,6 +1614,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;
index 2fb29b5f5f0540edb46b085cc1972cda3d2a809b..2237d119e63a726f3fba2678dd68358890e036a4 100644 (file)
@@ -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;