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

huangy81 at chinatelecom.cn huangy81 at chinatelecom.cn
Thu Jun 24 16:51:49 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  | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/conf/domain_conf.h  |  4 +++
 src/qemu/qemu_command.c |  3 ++
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d78f846..d972f1d 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;
 
@@ -17400,8 +17413,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);
@@ -17423,9 +17438,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;
 }
 
@@ -17575,7 +17618,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;
 
@@ -21671,7 +21714,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:
@@ -27649,6 +27712,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