[PATCH v6 3/4] conf: introduce dirty_ring_size field

huangy81 at chinatelecom.cn huangy81 at chinatelecom.cn
Sat Nov 20 08:20:47 UTC 2021


From: Hyman Huang(黄勇) <huangy81 at chinatelecom.cn>

introduce dirty_ring_size in struct "_virDomainDef" to hold
the ring size configured by user, and pass dirty_ring_size
when building qemu commandline if dirty ring feature enabled.

Signed-off-by: Hyman Huang(黄勇) <huangy81 at chinatelecom.cn>
---
 src/conf/domain_conf.c  | 76 ++++++++++++++++++++++++++++++++++++++++-
 src/conf/domain_conf.h  |  4 +++
 src/qemu/qemu_command.c |  3 ++
 3 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index deb32b3f6b..80a124557e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -205,6 +205,7 @@ VIR_ENUM_IMPL(virDomainKVM,
               "hint-dedicated",
               "poll-control",
               "pv-ipi",
+              "dirty-ring",
 );
 
 VIR_ENUM_IMPL(virDomainXen,
@@ -4826,6 +4827,18 @@ virDomainDefPostParseMemtune(virDomainDef *def)
 }
 
 
+static void
+virDomainDefPostParseFeatures(virDomainDef *def)
+{
+    if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON &&
+        def->kvm_features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON &&
+        def->dirty_ring_size == 0) {
+        /* set 4096 as default size if dirty ring size not congfigured */
+        def->dirty_ring_size = 4096;
+    }
+}
+
+
 static int
 virDomainDefAddConsoleCompat(virDomainDef *def)
 {
@@ -6062,6 +6075,8 @@ virDomainDefPostParseCommon(virDomainDef *def,
 
     virDomainDefPostParseMemtune(def);
 
+    virDomainDefPostParseFeatures(def);
+
     if (virDomainDefRejectDuplicateControllers(def) < 0)
         return -1;
 
@@ -17566,8 +17581,10 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
 
 static int
 virDomainFeaturesKVMDefParse(virDomainDef *def,
+                            xmlXPathContextPtr ctxt,
                              xmlNodePtr node)
 {
+    xmlNodePtr tmp_node = ctxt->node;
     def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
 
     node = xmlFirstElementChild(node);
@@ -17589,9 +17606,37 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
 
         def->kvm_features[feature] = value;
 
+        /* dirty ring feature should parse size property */
+        if ((virDomainKVM) feature == VIR_DOMAIN_KVM_DIRTY_RING) {
+            if (((virDomainKVM) feature) == VIR_DOMAIN_KVM_DIRTY_RING &&
+                  value == VIR_TRISTATE_SWITCH_ON) {
+                ctxt->node = node;
+
+                if (virXMLPropString(node, "size")) {
+                    if (virXPathUInt("string(./@size)", ctxt,
+                                     &def->dirty_ring_size) < 0) {
+                        virReportError(VIR_ERR_XML_ERROR, "%s",
+                                      _("invalid number of dirty ring size"));
+                        return -1;
+                    }
+
+                    if ((def->dirty_ring_size & (def->dirty_ring_size - 1)) != 0 ||
+                        def->dirty_ring_size < 1024 ||
+                        def->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);
     }
 
+    ctxt->node = tmp_node;
+
     return 0;
 }
 
@@ -17741,7 +17786,7 @@ virDomainFeaturesDefParse(virDomainDef *def,
             break;
 
         case VIR_DOMAIN_FEATURE_KVM:
-            if (virDomainFeaturesKVMDefParse(def, nodes[i]) < 0)
+            if (virDomainFeaturesKVMDefParse(def, ctxt, nodes[i]) < 0)
                 return -1;
             break;
 
@@ -21836,7 +21881,27 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
                                    virTristateSwitchTypeToString(dst->kvm_features[i]));
                     return false;
                 }
+                break;
 
+            case VIR_DOMAIN_KVM_DIRTY_RING:
+                if (src->kvm_features[i] != dst->kvm_features[i]) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("State of KVM feature '%s' differs: "
+                                     "source: '%s', destination: '%s'"),
+                                   virDomainKVMTypeToString(i),
+                                   virTristateSwitchTypeToString(src->kvm_features[i]),
+                                   virTristateSwitchTypeToString(dst->kvm_features[i]));
+                    return false;
+                }
+
+                if (src->dirty_ring_size != dst->dirty_ring_size) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("dirty ring size of KVM feature '%s' differs: "
+                                     "source: '%d', destination: '%d'"),
+                                   virDomainKVMTypeToString(i),
+                                   src->dirty_ring_size, dst->dirty_ring_size);
+                    return false;
+                }
                 break;
 
             case VIR_DOMAIN_KVM_LAST:
@@ -27884,6 +27949,15 @@ virDomainDefFormatFeatures(virBuffer *buf,
                                               def->kvm_features[j]));
                     break;
 
+                case VIR_DOMAIN_KVM_DIRTY_RING:
+                    if (def->kvm_features[j] != VIR_TRISTATE_SWITCH_ABSENT) {
+                        virBufferAsprintf(&childBuf, "<%s state='%s' size='%d'/>\n",
+                                          virDomainKVMTypeToString(j),
+                                          virTristateSwitchTypeToString(def->kvm_features[j]),
+                                          def->dirty_ring_size);
+                    }
+                    break;
+
                 case VIR_DOMAIN_KVM_LAST:
                     break;
                 }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8634960313..026edde88f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2084,6 +2084,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;
@@ -2933,6 +2934,9 @@ struct _virDomainDef {
                              should be re-run before starting */
 
     unsigned int scsiBusMaxUnit;
+
+    /* size of dirty ring for each vcpu */
+    unsigned int dirty_ring_size;
 };
 
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a8f73c2d3e..145596d11a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6860,6 +6860,9 @@ qemuBuildCpuCommandLine(virCommand *cmd,
                     virBufferAddLit(&buf, ",kvm-pv-ipi=off");
                 break;
 
+            case VIR_DOMAIN_KVM_DIRTY_RING:
+                break;
+
             case VIR_DOMAIN_KVM_LAST:
                 break;
             }
-- 
2.27.0





More information about the libvir-list mailing list