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