From: Hyman Huang(黄勇) <huangy81@xxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxx> --- 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