[PATCH v2 3/4] conf: introduce dirty_ring_size in struct "_virDomainDef"

huangy81 at chinatelecom.cn huangy81 at chinatelecom.cn
Wed Jun 23 14:58:17 UTC 2021


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

introduce dirty_ring_size 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  | 78 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h  |  4 +++
 src/qemu/qemu_command.c |  3 ++
 3 files changed, 85 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f65509d..09d2f95 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -204,6 +204,7 @@ VIR_ENUM_IMPL(virDomainKVM,
               "hidden",
               "hint-dedicated",
               "poll-control",
+              "dirty-ring",
 );
 
 VIR_ENUM_IMPL(virDomainXen,
@@ -4752,6 +4753,16 @@ 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)
@@ -6003,6 +6014,8 @@ virDomainDefPostParseCommon(virDomainDef *def,
 
     virDomainDefPostParseMemtune(def);
 
+    virDomainDefPostParseFeatures(def);
+
     if (virDomainDefRejectDuplicateControllers(def) < 0)
         return -1;
 
@@ -17574,6 +17587,9 @@ virDomainFeaturesDefParse(virDomainDef *def,
     if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
         int feature;
         virTristateSwitch value;
+        xmlNodePtr node = NULL;
+
+        node = ctxt->node;
         if ((n = virXPathNodeSet("./features/kvm/*", ctxt, &nodes)) < 0)
             return -1;
 
@@ -17598,11 +17614,44 @@ virDomainFeaturesDefParse(virDomainDef *def,
                     def->kvm_features[feature] = value;
                     break;
 
+                case VIR_DOMAIN_KVM_DIRTY_RING:
+                    if (virXMLPropTristateSwitch(nodes[i], "state",
+                                                 VIR_XML_PROP_REQUIRED,
+                                                 &value) < 0)
+                        return -1;
+
+                    def->kvm_features[feature] = value;
+
+                    if (((virDomainKVM) feature) == VIR_DOMAIN_KVM_DIRTY_RING &&
+                          value == VIR_TRISTATE_SWITCH_ON) {
+                        ctxt->node = nodes[i];
+
+                        if (virXMLPropString(ctxt->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;
+                            }
+                        }
+                    }
+                    break;
+
                 case VIR_DOMAIN_KVM_LAST:
                     break;
             }
         }
         VIR_FREE(nodes);
+        ctxt->node = node;
     }
 
     if (def->features[VIR_DOMAIN_FEATURE_XEN] == VIR_TRISTATE_SWITCH_ON) {
@@ -21636,7 +21685,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:
@@ -27614,6 +27683,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 f706c49..a479b68 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2058,6 +2058,7 @@ typedef enum {
     VIR_DOMAIN_KVM_HIDDEN = 0,
     VIR_DOMAIN_KVM_DEDICATED,
     VIR_DOMAIN_KVM_POLLCONTROL,
+    VIR_DOMAIN_KVM_DIRTY_RING,
 
     VIR_DOMAIN_KVM_LAST
 } virDomainKVM;
@@ -2882,6 +2883,9 @@ struct _virDomainDef {
                              callbacks failed for a non-critical reason
                              (was not able to fill in some data) and thus
                              should be re-run before starting */
+
+    /* 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 81fe67e..d1e9bee 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6587,6 +6587,9 @@ qemuBuildCpuCommandLine(virCommand *cmd,
                     virBufferAddLit(&buf, ",kvm-poll-control=on");
                 break;
 
+            case VIR_DOMAIN_KVM_DIRTY_RING:
+                break;
+
             case VIR_DOMAIN_KVM_LAST:
                 break;
             }
-- 
1.8.3.1





More information about the libvir-list mailing list