On Wed, Jan 13, 2021 at 1:09 AM <huangy81@chinatelecom.cn> wrote:
From: Hyman <huangy81@chinatelecom.cn>
QEMU introduced a dirty ring feature, this patch add a new
KVM feature 'dirty-ring' to set this feature for kvm guests.
To enable the feature, libvirt add "-accel dirty-gfn-count=xxx"
to QEMU command line, the following XML needs to be added to
the guest's domain description:
<features>
<kvm>
<dirty-ring state='on' size='xxx'>
</kvm>
</features>
Signed-off-by: Hyman <huangy81@chinatelecom.cn>
---
docs/formatdomain.rst | 16 +++++++++-------
docs/schemas/domaincommon.rng | 10 ++++++++++
src/conf/domain_conf.c | 34 ++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 4 ++++
src/qemu/qemu_command.c | 13 ++++++++++---
5 files changed, 67 insertions(+), 10 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 6100b88..5bf8517 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1767,6 +1767,7 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off.
<hidden state='on'/>
<hint-dedicated state='on'/>
<poll-control='on'/>
+ <dirty-ring state='on' size='4096'/>
</kvm>
<xen>
<e820_host state='on'/>
@@ -1849,13 +1850,14 @@ are:
``kvm``
Various features to change the behavior of the KVM hypervisor.
- ============== ============================================================================ ======= ============================
- Feature Description Value Since
- ============== ============================================================================ ======= ============================
- hidden Hide the KVM hypervisor from standard MSR based discovery on, off :since:`1.2.8 (QEMU 2.1.0)`
- hint-dedicated Allows a guest to enable optimizations when running on dedicated vCPUs on, off :since:`5.7.0 (QEMU 2.12.0)`
- poll-control Decrease IO completion latency by introducing a grace period of busy waiting on, off :since:`6.10.0 (QEMU 4.2)`
- ============== ============================================================================ ======= ============================
+ ============== ============================================================================ ================================== ============================
+ Feature Description Value Since
+ ============== ============================================================================ ================================== ============================
+ hidden Hide the KVM hypervisor from standard MSR based discovery on, off :since:`1.2.8 (QEMU 2.1.0)`
+ hint-dedicated Allows a guest to enable optimizations when running on dedicated vCPUs on, off :since:`5.7.0 (QEMU 2.12.0)`
+ poll-control Decrease IO completion latency by introducing a grace period of busy waiting on, off :since:`6.10.0 (QEMU 4.2)`
+ dirty-ring Enable dirty ring feature on, off; size - must be power of 2 :since:`7.0.0 (QEMU 5.2.1)`
Are you sure it will be added in QEMU 5.2.1 ?I find it has been not merged in qemu yet
indeed, it hasn't been merged. This patchset base on the
following works:
https://lore.kernel.org/qemu-devel/20210108164601.406146-1-peterx@redhat.com/
Maybe the review is under way. I post this patchset for review in
advance. Once the qemu patchset is merged, i'll ping the
libvir-list and apply for merging.
+ ============== ============================================================================ ================================== ============================
``xen``
Various features to change the behavior of the Xen hypervisor.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 7dc419b..5af4bbe 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -6569,6 +6569,16 @@
<ref name="featurestate"/>
</element>
</optional>
+ <optional>
+ <element name="dirty-ring">
+ <ref name="featurestate"/>
+ <optional>
+ <attribute name="size">
+ <data type="unsignedInt"/>
+ </attribute>
+ </optional>
+ </element>
+ </optional>
</interleave>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 349fc28..e617b95 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -186,6 +186,7 @@ VIR_ENUM_IMPL(virDomainKVM,
"hidden",
"hint-dedicated",
"poll-control",
+ "dirty-ring",
);
VIR_ENUM_IMPL(virDomainXen,
@@ -18379,6 +18380,7 @@ virDomainFeaturesDefParse(virDomainDefPtr def,
if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
int feature;
int value;
+ node = ctxt->node;
if ((n = virXPathNodeSet("./features/kvm/*", ctxt, &nodes)) < 0)
return -1;
@@ -18395,6 +18397,7 @@ virDomainFeaturesDefParse(virDomainDefPtr def,
case VIR_DOMAIN_KVM_HIDDEN:
case VIR_DOMAIN_KVM_DEDICATED:
case VIR_DOMAIN_KVM_POLLCONTROL:
+ case VIR_DOMAIN_KVM_DIRTY_RING:
if (!(tmp = virXMLPropString(nodes[i], "state"))) {
virReportError(VIR_ERR_XML_ERROR,
_("missing 'state' attribute for "
@@ -18413,6 +18416,26 @@ virDomainFeaturesDefParse(virDomainDefPtr def,
VIR_FREE(tmp);
def->kvm_features[feature] = value;
+
+ /* only for dirty ring case */
+ if (((virDomainKVM) feature) == VIR_DOMAIN_KVM_DIRTY_RING &&
+ value == VIR_TRISTATE_SWITCH_ON) {
+ ctxt->node = nodes[i];
+ if (virXPathUInt("string(./@size)", ctxt,
+ &def->dirty_gfn_count) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("invalid number of dirty GFNs"));
+ return -1;
+ }
+
+ if ((def->dirty_gfn_count & (def->dirty_gfn_count - 1)) ||
+ def->dirty_gfn_count > 65536) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("max number of dirty GFNs is 65536 "
+ "and must be power of 2"));
+ return -1;
+ }
+ }
break;
/* coverity[dead_error_begin] */
@@ -18421,6 +18444,7 @@ virDomainFeaturesDefParse(virDomainDefPtr def,
}
}
VIR_FREE(nodes);
+ ctxt->node = node;
}
if (def->features[VIR_DOMAIN_FEATURE_XEN] == VIR_TRISTATE_SWITCH_ON) {
@@ -22521,6 +22545,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
case VIR_DOMAIN_KVM_HIDDEN:
case VIR_DOMAIN_KVM_DEDICATED:
case VIR_DOMAIN_KVM_POLLCONTROL:
+ 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: "
@@ -28271,6 +28296,15 @@ virDomainDefFormatFeatures(virBufferPtr buf,
def->kvm_features[j]));
break;
+ case VIR_DOMAIN_KVM_DIRTY_RING:
+ if (def->kvm_features[j])
+ virBufferAsprintf(&childBuf, "<%s state='%s' size='%d'/>\n",
+ virDomainKVMTypeToString(j),
+ virTristateSwitchTypeToString(
+ def->kvm_features[j]),
+ def->dirty_gfn_count);
+ break;
+
/* coverity[dead_error_begin] */
case VIR_DOMAIN_KVM_LAST:
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ec43bbe..120d490 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1917,6 +1917,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;
@@ -2728,6 +2729,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 */
+
+ /* Number of dirty GFNs per ring */
+ unsigned int dirty_gfn_count;
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0f660aa..31829ba 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6525,6 +6525,9 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
virBufferAddLit(&buf, ",kvm-poll-control=on");
break;
+ case VIR_DOMAIN_KVM_DIRTY_RING:
+ break;
+
/* coverity[dead_error_begin] */
case VIR_DOMAIN_KVM_LAST:
break;
@@ -6959,9 +6962,13 @@ qemuBuildAccelCommandLineTcgOptions(void)
static void
-qemuBuildAccelCommandLineKvmOptions(void)
+qemuBuildAccelCommandLineKvmOptions(virBuffer *buf,
+ const virDomainDef *def)
{
- /* implemented in the next patch */
+ if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON &&
+ def->kvm_features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) {
+ virBufferAsprintf(buf, ",dirty-gfn-count=%d", def->dirty_gfn_count);
+ }
}
@@ -6982,7 +6989,7 @@ qemuBuildAccelCommandLine(virCommandPtr cmd,
case VIR_DOMAIN_VIRT_KVM:
virBufferAddLit(&buf, "kvm");
- qemuBuildAccelCommandLineKvmOptions();
+ qemuBuildAccelCommandLineKvmOptions(&buf, def);
break;
case VIR_DOMAIN_VIRT_KQEMU:
--
1.8.3.1