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