]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: support dirty ring feature
authorHyman Huang(黄勇) <huangy81@chinatelecom.cn>
Tue, 23 Nov 2021 14:36:58 +0000 (09:36 -0500)
committerMichal Privoznik <mprivozn@redhat.com>
Tue, 14 Dec 2021 12:17:41 +0000 (13:17 +0100)
Dirty ring feature was introduced in qemu-6.1.0, this patch
add the corresponding feature named 'dirty-ring', which enable
dirty ring feature when starting VM.

To enable the feature, the following XML needs to be added to
the guest's domain description:

<features>
   <kvm>
     <dirty-ring state='on' size='xxx'>
   </kvm>
</features>

If property "state=on", property "size" must be specified, which
should be power of 2 and range in [1024, 65526].

Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
docs/formatdomain.rst
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_command.c
tests/qemuxml2argvdata/kvm-features-off.xml
tests/qemuxml2argvdata/kvm-features.xml
tests/qemuxml2xmloutdata/kvm-features-off.xml
tests/qemuxml2xmloutdata/kvm-features.xml

index 98eb7b7481c89501a719911ff387faa4a7949508..097796df7212285155d717bee7a48bf9aa02a985 100644 (file)
@@ -1843,6 +1843,7 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off.
        <hint-dedicated state='on'/>
        <poll-control state='on'/>
        <pv-ipi state='off'/>
+       <dirty-ring state='on' size='4096'/>
      </kvm>
      <xen>
        <e820_host state='on'/>
@@ -1928,14 +1929,15 @@ are:
 ``kvm``
    Various features to change the behavior of the KVM hypervisor.
 
-   ============== ============================================================================ ======= ============================
-   Feature        Description                                                                  Value   Since
-   ============== ============================================================================ ======= ============================
-   hidden         Hide the KVM hypervisor from standard MSR based discovery                    on, off :since:`1.2.8 (QEMU 2.1.0)`
-   hint-dedicated Allows a guest to enable optimizations when running on dedicated vCPUs       on, off :since:`5.7.0 (QEMU 2.12.0)`
-   poll-control   Decrease IO completion latency by introducing a grace period of busy waiting on, off :since:`6.10.0 (QEMU 4.2)`
-   pv-ipi         Paravirtualized send IPIs                                                    on, off :since:`7.10.0 (QEMU 3.1)`
-   ============== ============================================================================ ======= ============================
+   ============== ============================================================================ ====================================================== ============================
+   Feature        Description                                                                  Value                                                  Since
+   ============== ============================================================================ ====================================================== ============================
+   hidden         Hide the KVM hypervisor from standard MSR based discovery                    on, off                                                :since:`1.2.8 (QEMU 2.1.0)`
+   hint-dedicated Allows a guest to enable optimizations when running on dedicated vCPUs       on, off                                                :since:`5.7.0 (QEMU 2.12.0)`
+   poll-control   Decrease IO completion latency by introducing a grace period of busy waiting on, off                                                :since:`6.10.0 (QEMU 4.2)`
+   pv-ipi         Paravirtualized send IPIs                                                    on, off                                                :since:`7.10.0 (QEMU 3.1)`
+   dirty-ring     Enable dirty ring feature                                                    on, off; size - must be power of 2, range [1024,65536] :since:`8.0.0 (QEMU 6.1)`
+   ============== ============================================================================ ====================================================== ============================
 
 ``xen``
    Various features to change the behavior of the Xen hypervisor.
index ce51e95895b8226158ebc1c4f85b1ef1ecef74e5..736cb35d4e04359f4eaa01b133ac24e27d5042c3 100644 (file)
             <ref name="featurestate"/>
           </element>
         </optional>
+        <optional>
+          <element name="dirty-ring">
+            <ref name="featurestate"/>
+            <optional>
+              <attribute name="size">
+                <data type="unsignedInt"/>
+              </attribute>
+            </optional>
+          </element>
+        </optional>
       </interleave>
     </element>
   </define>
index 07cbfa24bc8502540e6d89ae4a3e0281d7f43d75..cd87057524124b736a0796b4934c10f809531eb1 100644 (file)
@@ -206,6 +206,7 @@ VIR_ENUM_IMPL(virDomainKVM,
               "hint-dedicated",
               "poll-control",
               "pv-ipi",
+              "dirty-ring",
 );
 
 VIR_ENUM_IMPL(virDomainXen,
@@ -17556,6 +17557,25 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
 
         kvm->features[feature] = value;
 
+        /* dirty ring feature should parse size property */
+        if (feature == VIR_DOMAIN_KVM_DIRTY_RING &&
+            value == VIR_TRISTATE_SWITCH_ON) {
+
+            if (virXMLPropUInt(node, "size", 0, VIR_XML_PROP_REQUIRED,
+                               &kvm->dirty_ring_size) < 0) {
+                return -1;
+            }
+
+            if (!VIR_IS_POW2(kvm->dirty_ring_size) ||
+                kvm->dirty_ring_size < 1024 ||
+                kvm->dirty_ring_size > 65536) {
+                virReportError(VIR_ERR_XML_ERROR, "%s",
+                               _("dirty ring must be power of 2 and ranges [1024, 65536]"));
+
+                return -1;
+            }
+        }
+
         node = xmlNextElementSibling(node);
     }
 
@@ -21809,6 +21829,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
             case VIR_DOMAIN_KVM_DEDICATED:
             case VIR_DOMAIN_KVM_POLLCONTROL:
             case VIR_DOMAIN_KVM_PVIPI:
+            case VIR_DOMAIN_KVM_DIRTY_RING:
                 if (src->kvm_features->features[i] != dst->kvm_features->features[i]) {
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                    _("State of KVM feature '%s' differs: "
@@ -21825,6 +21846,16 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
                 break;
             }
         }
+
+        if (src->kvm_features->dirty_ring_size != dst->kvm_features->dirty_ring_size) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("dirty ring size of KVM feature '%s' differs: "
+                             "source: '%d', destination: '%d'"),
+                           virDomainKVMTypeToString(i),
+                           src->kvm_features->dirty_ring_size,
+                           dst->kvm_features->dirty_ring_size);
+            return false;
+        }
     }
 
     /* smm */
@@ -27886,6 +27917,20 @@ virDomainDefFormatFeatures(virBuffer *buf,
                                               def->kvm_features->features[j]));
                     break;
 
+                case VIR_DOMAIN_KVM_DIRTY_RING:
+                    if (def->kvm_features->features[j] != VIR_TRISTATE_SWITCH_ABSENT) {
+                        virBufferAsprintf(&childBuf, "<%s state='%s'",
+                                          virDomainKVMTypeToString(j),
+                                          virTristateSwitchTypeToString(def->kvm_features->features[j]));
+                        if (def->kvm_features->dirty_ring_size > 0) {
+                            virBufferAsprintf(&childBuf, " size='%d'/>\n",
+                                              def->kvm_features->dirty_ring_size);
+                        } else {
+                            virBufferAddLit(&childBuf, "/>\n");
+                        }
+                    }
+                    break;
+
                 case VIR_DOMAIN_KVM_LAST:
                     break;
                 }
index 5613d621bbc7da6b5756b09ceb70097b929a85af..a3d2f5c7dc703aba09e2081d4f7c6a15f86a606f 100644 (file)
@@ -2085,6 +2085,7 @@ typedef enum {
     VIR_DOMAIN_KVM_DEDICATED,
     VIR_DOMAIN_KVM_POLLCONTROL,
     VIR_DOMAIN_KVM_PVIPI,
+    VIR_DOMAIN_KVM_DIRTY_RING,
 
     VIR_DOMAIN_KVM_LAST
 } virDomainKVM;
@@ -2266,6 +2267,8 @@ VIR_ENUM_DECL(virDomainIBS);
 typedef struct _virDomainFeatureKVM virDomainFeatureKVM;
 struct _virDomainFeatureKVM {
     int features[VIR_DOMAIN_KVM_LAST];
+
+    unsigned int dirty_ring_size; /* size of dirty ring for each vCPU, no units */
 };
 
 typedef struct _virDomainFeatureTCG virDomainFeatureTCG;
index 7cdec9f9100f13bdc9134aeea54c1b95360d65da..65e7d77a079ce9aeca8611371e2a5685eb52ba82 100644 (file)
@@ -6784,6 +6784,9 @@ qemuBuildCpuCommandLine(virCommand *cmd,
                     virBufferAddLit(&buf, ",kvm-pv-ipi=off");
                 break;
 
+            case VIR_DOMAIN_KVM_DIRTY_RING:
+                break;
+
             case VIR_DOMAIN_KVM_LAST:
                 break;
             }
index a1004a206b982d96941afa92dfda3ad3dd2f6c29..fb7cbaf0610486b58daee43862c12fae255fd323 100644 (file)
@@ -15,6 +15,7 @@
       <hint-dedicated state='off'/>
       <poll-control state='off'/>
       <pv-ipi state='off'/>
+      <dirty-ring state='off'/>
     </kvm>
   </features>
   <cpu mode='host-passthrough' check='none'/>
index 51229a6c373190fa4e59a4b13ef65269a06aca57..900431c4ffca672bbfbf82f827902fe6cb7240a7 100644 (file)
@@ -15,6 +15,7 @@
       <hint-dedicated state='on'/>
       <poll-control state='on'/>
       <pv-ipi state='on'/>
+      <dirty-ring state='on' size='4096'/>
     </kvm>
   </features>
   <cpu mode='host-passthrough' check='none'/>
index 52a0ef00656a276fa1e6a2f05e211ffdeaff5ecb..7ee6525cd94681532c17324ccb3553e4ed198247 100644 (file)
@@ -15,6 +15,7 @@
       <hint-dedicated state='off'/>
       <poll-control state='off'/>
       <pv-ipi state='off'/>
+      <dirty-ring state='off'/>
     </kvm>
   </features>
   <cpu mode='host-passthrough' check='none' migratable='off'/>
index 72e66fcbf524ea3ccd10f00a5cb2075971334422..8ce3a2b98714bd5557fb645f8234c33018b59722 100644 (file)
@@ -15,6 +15,7 @@
       <hint-dedicated state='on'/>
       <poll-control state='on'/>
       <pv-ipi state='on'/>
+      <dirty-ring state='on' size='4096'/>
     </kvm>
   </features>
   <cpu mode='host-passthrough' check='none' migratable='off'/>