<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jan 13, 2021 at 1:09 AM <<a href="mailto:huangy81@chinatelecom.cn">huangy81@chinatelecom.cn</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Hyman <<a href="mailto:huangy81@chinatelecom.cn" target="_blank">huangy81@chinatelecom.cn</a>><br>
<br>
QEMU introduced a dirty ring feature, this patch add a new<br>
KVM feature 'dirty-ring' to set this feature for kvm guests.<br>
<br>
To enable the feature, libvirt add "-accel dirty-gfn-count=xxx"<br>
to QEMU command line, the following XML needs to be added to<br>
the guest's domain description:<br>
<br>
<features><br>
  <kvm><br>
    <dirty-ring state='on' size='xxx'><br>
  </kvm><br>
</features><br>
<br>
Signed-off-by: Hyman <<a href="mailto:huangy81@chinatelecom.cn" target="_blank">huangy81@chinatelecom.cn</a>><br>
---<br>
 docs/formatdomain.rst         | 16 +++++++++-------<br>
 docs/schemas/domaincommon.rng | 10 ++++++++++<br>
 src/conf/domain_conf.c        | 34 ++++++++++++++++++++++++++++++++++<br>
 src/conf/domain_conf.h        |  4 ++++<br>
 src/qemu/qemu_command.c       | 13 ++++++++++---<br>
 5 files changed, 67 insertions(+), 10 deletions(-)<br>
<br>
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst<br>
index 6100b88..5bf8517 100644<br>
--- a/docs/formatdomain.rst<br>
+++ b/docs/formatdomain.rst<br>
@@ -1767,6 +1767,7 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off.<br>
        <hidden state='on'/><br>
        <hint-dedicated state='on'/><br>
        <poll-control='on'/><br>
+       <dirty-ring state='on' size='4096'/><br>
      </kvm><br>
      <xen><br>
        <e820_host state='on'/><br>
@@ -1849,13 +1850,14 @@ are:<br>
 ``kvm``<br>
    Various features to change the behavior of the KVM hypervisor.<br>
<br>
-   ============== ============================================================================ ======= ============================<br>
-   Feature        Description                                                                  Value   Since<br>
-   ============== ============================================================================ ======= ============================<br>
-   hidden         Hide the KVM hypervisor from standard MSR based discovery                    on, off :since:`1.2.8 (QEMU 2.1.0)`<br>
-   hint-dedicated Allows a guest to enable optimizations when running on dedicated vCPUs       on, off :since:`5.7.0 (QEMU 2.12.0)`<br>
-   poll-control   Decrease IO completion latency by introducing a grace period of busy waiting on, off :since:`6.10.0 (QEMU 4.2)`<br>
-   ============== ============================================================================ ======= ============================<br>
+   ============== ============================================================================ ================================== ============================<br>
+   Feature        Description                                                                  Value                              Since<br>
+   ============== ============================================================================ ================================== ============================<br>
+   hidden         Hide the KVM hypervisor from standard MSR based discovery                    on, off                            :since:`1.2.8 (QEMU 2.1.0)`<br>
+   hint-dedicated Allows a guest to enable optimizations when running on dedicated vCPUs       on, off                            :since:`5.7.0 (QEMU 2.12.0)`<br>
+   poll-control   Decrease IO completion latency by introducing a grace period of busy waiting on, off                            :since:`6.10.0 (QEMU 4.2)`<br>
+   dirty-ring     Enable dirty ring feature                                                    on, off; size - must be power of 2 :since:`7.0.0 (QEMU 5.2.1)`<br></blockquote><div>Are you sure it will be added in QEMU 5.2.1 ?</div><div>I find it has been not merged in qemu yet<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+   ============== ============================================================================ ================================== ============================<br>
<br>
 ``xen``<br>
    Various features to change the behavior of the Xen hypervisor.<br>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng<br>
index 7dc419b..5af4bbe 100644<br>
--- a/docs/schemas/domaincommon.rng<br>
+++ b/docs/schemas/domaincommon.rng<br>
@@ -6569,6 +6569,16 @@<br>
             <ref name="featurestate"/><br>
           </element><br>
         </optional><br>
+        <optional><br>
+          <element name="dirty-ring"><br>
+            <ref name="featurestate"/><br>
+            <optional><br>
+              <attribute name="size"><br>
+                <data type="unsignedInt"/><br>
+              </attribute><br>
+            </optional><br>
+          </element><br>
+        </optional><br>
       </interleave><br>
     </element><br>
   </define><br>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c<br>
index 349fc28..e617b95 100644<br>
--- a/src/conf/domain_conf.c<br>
+++ b/src/conf/domain_conf.c<br>
@@ -186,6 +186,7 @@ VIR_ENUM_IMPL(virDomainKVM,<br>
               "hidden",<br>
               "hint-dedicated",<br>
               "poll-control",<br>
+              "dirty-ring",<br>
 );<br>
<br>
 VIR_ENUM_IMPL(virDomainXen,<br>
@@ -18379,6 +18380,7 @@ virDomainFeaturesDefParse(virDomainDefPtr def,<br>
     if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {<br>
         int feature;<br>
         int value;<br>
+        node = ctxt->node;<br>
         if ((n = virXPathNodeSet("./features/kvm/*", ctxt, &nodes)) < 0)<br>
             return -1;<br>
<br>
@@ -18395,6 +18397,7 @@ virDomainFeaturesDefParse(virDomainDefPtr def,<br>
                 case VIR_DOMAIN_KVM_HIDDEN:<br>
                 case VIR_DOMAIN_KVM_DEDICATED:<br>
                 case VIR_DOMAIN_KVM_POLLCONTROL:<br>
+                case VIR_DOMAIN_KVM_DIRTY_RING:<br>
                     if (!(tmp = virXMLPropString(nodes[i], "state"))) {<br>
                         virReportError(VIR_ERR_XML_ERROR,<br>
                                        _("missing 'state' attribute for "<br>
@@ -18413,6 +18416,26 @@ virDomainFeaturesDefParse(virDomainDefPtr def,<br>
<br>
                     VIR_FREE(tmp);<br>
                     def->kvm_features[feature] = value;<br>
+<br>
+                    /* only for dirty ring case */<br>
+                    if (((virDomainKVM) feature) == VIR_DOMAIN_KVM_DIRTY_RING &&<br>
+                          value == VIR_TRISTATE_SWITCH_ON) {<br>
+                        ctxt->node = nodes[i];<br>
+                        if (virXPathUInt("string(./@size)", ctxt,<br>
+                                         &def->dirty_gfn_count) < 0) {<br>
+                            virReportError(VIR_ERR_XML_ERROR, "%s",<br>
+                                           _("invalid number of dirty GFNs"));<br>
+                            return -1;<br>
+                        }<br>
+<br>
+                        if ((def->dirty_gfn_count & (def->dirty_gfn_count - 1)) ||<br>
+                            def->dirty_gfn_count > 65536) {<br>
+                            virReportError(VIR_ERR_XML_ERROR, "%s",<br>
+                                           _("max number of dirty GFNs is 65536 "<br>
+                                             "and must be power of 2"));<br>
+                            return -1;<br>
+                        }<br>
+                    }<br>
                     break;<br>
<br>
                 /* coverity[dead_error_begin] */<br>
@@ -18421,6 +18444,7 @@ virDomainFeaturesDefParse(virDomainDefPtr def,<br>
             }<br>
         }<br>
         VIR_FREE(nodes);<br>
+        ctxt->node = node;<br>
     }<br>
<br>
     if (def->features[VIR_DOMAIN_FEATURE_XEN] == VIR_TRISTATE_SWITCH_ON) {<br>
@@ -22521,6 +22545,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,<br>
             case VIR_DOMAIN_KVM_HIDDEN:<br>
             case VIR_DOMAIN_KVM_DEDICATED:<br>
             case VIR_DOMAIN_KVM_POLLCONTROL:<br>
+            case VIR_DOMAIN_KVM_DIRTY_RING:<br>
                 if (src->kvm_features[i] != dst->kvm_features[i]) {<br>
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,<br>
                                    _("State of KVM feature '%s' differs: "<br>
@@ -28271,6 +28296,15 @@ virDomainDefFormatFeatures(virBufferPtr buf,<br>
                                               def->kvm_features[j]));<br>
                     break;<br>
<br>
+                case VIR_DOMAIN_KVM_DIRTY_RING:<br>
+                    if (def->kvm_features[j])<br>
+                        virBufferAsprintf(&childBuf, "<%s state='%s' size='%d'/>\n",<br>
+                                          virDomainKVMTypeToString(j),<br>
+                                          virTristateSwitchTypeToString(<br>
+                                              def->kvm_features[j]),<br>
+                                          def->dirty_gfn_count);<br>
+                    break;<br>
+<br>
                 /* coverity[dead_error_begin] */<br>
                 case VIR_DOMAIN_KVM_LAST:<br>
                     break;<br>
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h<br>
index ec43bbe..120d490 100644<br>
--- a/src/conf/domain_conf.h<br>
+++ b/src/conf/domain_conf.h<br>
@@ -1917,6 +1917,7 @@ typedef enum {<br>
     VIR_DOMAIN_KVM_HIDDEN = 0,<br>
     VIR_DOMAIN_KVM_DEDICATED,<br>
     VIR_DOMAIN_KVM_POLLCONTROL,<br>
+    VIR_DOMAIN_KVM_DIRTY_RING,<br>
<br>
     VIR_DOMAIN_KVM_LAST<br>
 } virDomainKVM;<br>
@@ -2728,6 +2729,9 @@ struct _virDomainDef {<br>
                              callbacks failed for a non-critical reason<br>
                              (was not able to fill in some data) and thus<br>
                              should be re-run before starting */<br>
+<br>
+    /* Number of dirty GFNs per ring */<br>
+    unsigned int dirty_gfn_count;<br>
 };<br>
<br>
<br>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c<br>
index 0f660aa..31829ba 100644<br>
--- a/src/qemu/qemu_command.c<br>
+++ b/src/qemu/qemu_command.c<br>
@@ -6525,6 +6525,9 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,<br>
                     virBufferAddLit(&buf, ",kvm-poll-control=on");<br>
                 break;<br>
<br>
+            case VIR_DOMAIN_KVM_DIRTY_RING:<br>
+                break;<br>
+<br>
             /* coverity[dead_error_begin] */<br>
             case VIR_DOMAIN_KVM_LAST:<br>
                 break;<br>
@@ -6959,9 +6962,13 @@ qemuBuildAccelCommandLineTcgOptions(void)<br>
<br>
<br>
 static void<br>
-qemuBuildAccelCommandLineKvmOptions(void)<br>
+qemuBuildAccelCommandLineKvmOptions(virBuffer *buf,<br>
+                                    const virDomainDef *def)<br>
 {<br>
-    /* implemented in the next patch */<br>
+    if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON &&<br>
+        def->kvm_features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) {<br>
+        virBufferAsprintf(buf, ",dirty-gfn-count=%d", def->dirty_gfn_count);<br>
+    }<br>
 }<br>
<br>
<br>
@@ -6982,7 +6989,7 @@ qemuBuildAccelCommandLine(virCommandPtr cmd,<br>
<br>
     case VIR_DOMAIN_VIRT_KVM:<br>
         virBufferAddLit(&buf, "kvm");<br>
-        qemuBuildAccelCommandLineKvmOptions();<br>
+        qemuBuildAccelCommandLineKvmOptions(&buf, def);<br>
         break;<br>
<br>
     case VIR_DOMAIN_VIRT_KQEMU:<br>
-- <br>
1.8.3.1<br>
<br>
</blockquote></div></div>