On Wed, Jan 13, 2021 at 1:09 AM <huang...@chinatelecom.cn> wrote: > From: Hyman <huang...@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 <huang...@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
> + ============== > ============================================================================ > ================================== ============================ > > ``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 > >