[PATCH Libvirt v2 02/10] conf: Introduce XML for dirty limit configuration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hyman Huang(黄勇) <yong.huang@xxxxxxxxxx>

The upper limit (MB/s) of the dirty page rate configured by the
user can be tracked by the XML. To allow this, add the following
XML:

<domain>
  ...
  <vcpu current='2'>3</vcpu>
  <vcpus>
    <vcpu id='0' hotpluggable='no' dirty_limit='10' order='1'.../>
    <vcpu id='1' hotpluggable='yes' dirty_limit='10' order='2'.../>
  </vcpus>
  ...

The "dirty_limit" attribute in "vcpu" sub-element within "vcpus"
element allows to set an upper limit for the individual vCPU. The
value can be set dynamically by limit-dirty-page-rate API.

Note that the dirty limit feature is based on the dirty-ring
feature, so it requires dirty-ring size configuration in XML.

Signed-off-by: Hyman Huang(黄勇) <yong.huang@xxxxxxxxxx>
---
 docs/formatdomain.rst             |  7 ++++++-
 src/conf/domain_conf.c            | 26 ++++++++++++++++++++++++
 src/conf/domain_conf.h            |  8 ++++++++
 src/conf/domain_validate.c        | 33 +++++++++++++++++++++++++++++++
 src/conf/schemas/domaincommon.rng |  5 +++++
 5 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index cd9cb02bf8..7305ba38ea 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -649,7 +649,7 @@ CPU Allocation
      ...
      <vcpu placement='static' cpuset="1-4,^3,6" current="1">2</vcpu>
      <vcpus>
-       <vcpu id='0' enabled='yes' hotpluggable='no' order='1'/>
+       <vcpu id='0' enabled='yes' hotpluggable='no' order='1' dirty_limit='64'/>
        <vcpu id='1' enabled='no' hotpluggable='yes'/>
      </vcpus>
      ...
@@ -715,6 +715,11 @@ CPU Allocation
    be enabled and non-hotpluggable. On PPC64 along with it vCPUs that are in the
    same core need to be enabled as well. All non-hotpluggable CPUs present at
    boot need to be grouped after vCPU 0. :since:`Since 2.2.0 (QEMU only)`
+   ``dirty_limit`` :since:`Since 9.6.0 (QEMU and KVM only)`
+   The optional attribute ``dirty_limit`` allows to set an upper limit (MB/s)
+   of the dirty page rate for the vCPU. User can change the upper limit value
+   dynamically by using ``limit-dirty-page-rate`` API. Require ``dirty-ring``
+   size configured.
 
 
 IOThreads Allocation
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 47693a49bf..0af6ddd358 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -17061,6 +17061,7 @@ virDomainVcpuParse(virDomainDef *def,
                    virDomainXMLOption *xmlopt)
 {
     int n;
+    int rv;
     xmlNodePtr vcpuNode;
     size_t i;
     unsigned int maxvcpus;
@@ -17148,6 +17149,13 @@ virDomainVcpuParse(virDomainDef *def,
             if (virXMLPropUInt(nodes[i], "order", 10, VIR_XML_PROP_NONE,
                                &vcpu->order) < 0)
                 return -1;
+
+            if ((rv = virXMLPropULongLong(nodes[i], "dirty_limit", 10, VIR_XML_PROP_NONNEGATIVE,
+                                          &vcpu->dirty_limit)) < 0) {
+                return -1;
+            } else if (rv > 0) {
+                vcpu->dirtyLimitSet = true;
+            }
         }
     } else {
         if (virDomainDefSetVcpus(def, vcpus) < 0)
@@ -21147,6 +21155,20 @@ virDomainDefVcpuCheckAbiStability(virDomainDef *src,
                            i);
             return false;
         }
+
+        if (svcpu->dirtyLimitSet != dvcpu->dirtyLimitSet) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("Dirty limit state of vCPU '%1$zu' differs between source and destination definitions"),
+                           i);
+            return false;
+        }
+
+        if (svcpu->dirty_limit != dvcpu->dirty_limit) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("Dirty limit of vCPU '%1$zu' differs between source and destination definitions"),
+                           i);
+            return false;
+        }
     }
 
     return true;
@@ -26712,6 +26734,10 @@ virDomainCpuDefFormat(virBuffer *buf,
             if (vcpu->order != 0)
                 virBufferAsprintf(buf, " order='%d'", vcpu->order);
 
+            if (vcpu->dirtyLimitSet) {
+                virBufferAsprintf(buf, " dirty_limit='%llu'", vcpu->dirty_limit);
+            }
+
             virBufferAddLit(buf, "/>\n");
         }
         virBufferAdjustIndent(buf, -2);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index c857ba556f..7e8bfcb884 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2785,6 +2785,14 @@ struct _virDomainVcpuDef {
     virDomainThreadSchedParam sched;
 
     virObject *privateData;
+
+    /* set to true if the dirty page rate upper limit for
+     * the virtual CPU is configured
+     * */
+    bool dirtyLimitSet;
+
+    /* dirty page rate upper limit */
+    unsigned long long dirty_limit;
 };
 
 struct _virDomainBlkiotune {
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index ad383b604e..db3b7e1d9d 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1798,6 +1798,36 @@ virDomainDefValidateIOThreads(const virDomainDef *def)
     return 0;
 }
 
+static int
+virDomainDefHasDirtyLimitStartupVcpus(const virDomainDef *def)
+{
+    size_t maxvcpus = virDomainDefGetVcpusMax(def);
+    virDomainVcpuDef *vcpu;
+    size_t i;
+
+    for (i = 0; i < maxvcpus; i++) {
+        vcpu = def->vcpus[i];
+
+        if (vcpu->dirtyLimitSet && (vcpu->dirty_limit != 0))
+            return true;
+    }
+
+    return false;
+}
+
+static int
+virDomainDefDirtyLimitValidate(const virDomainDef *def)
+{
+    if (virDomainDefHasDirtyLimitStartupVcpus(def)) {
+        if (def->kvm_features->dirty_ring_size == 0) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("Dirty limit requires dirty-ring size configuration"));
+            return -1;
+        }
+    }
+
+    return 0;
+}
 
 static int
 virDomainDefValidateInternal(const virDomainDef *def,
@@ -1854,6 +1884,9 @@ virDomainDefValidateInternal(const virDomainDef *def,
     if (virDomainDefValidateIOThreads(def) < 0)
         return -1;
 
+    if (virDomainDefDirtyLimitValidate(def) < 0)
+        return -1;
+
     return 0;
 }
 
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index c2f56b0490..da0986b7c3 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -859,6 +859,11 @@
                   <ref name="unsignedInt"/>
                 </attribute>
               </optional>
+              <optional>
+                <attribute name="dirty_limit">
+                  <ref name="unsignedLong"/>
+                </attribute>
+              </optional>
             </element>
           </zeroOrMore>
         </element>
-- 
2.38.5





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux