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 | 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