From: Hyman Huang(黄勇) <huangy81@xxxxxxxxxxxxxxx> Dirty ring feature was introduced in qemu-6.1.0, this patch add the corresponding feature named 'dirty-ring', which enable dirty ring feature when starting vm. To implement the dirty-ring feature, dirty_ring_size in struct "_virDomainDef" is introduced to hold the dirty ring size configured in xml, and it will be used as dirty-ring-size property of kvm accelerator when building qemu commandline, it is something like "-accel dirty-ring-size=xxx". To enable the feature, the following XML needs to be added to the guest's domain description: <features> <kvm> <dirty-ring state='on' size='xxx'> </kvm> </features> If property "state=on", property "size" must be specified, which should be power of 2 and range in [1024, 65526]. Signed-off-by: Hyman Huang(黄勇) <huangy81@xxxxxxxxxxxxxxx> --- docs/formatdomain.rst | 18 ++++++------ docs/schemas/domaincommon.rng | 10 +++++++ src/conf/domain_conf.c | 54 +++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 4 +++ src/qemu/qemu_command.c | 12 ++++++++ 5 files changed, 90 insertions(+), 8 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index eb8c973cf1..ea69b61c70 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -1843,6 +1843,7 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off. <hint-dedicated state='on'/> <poll-control state='on'/> <pv-ipi state='off'/> + <dirty-ring state='on' size='4096'/> </kvm> <xen> <e820_host state='on'/> @@ -1925,14 +1926,15 @@ 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)` - pv-ipi Paravirtualized send IPIs on, off :since:`7.10.0 (QEMU 3.1)` - ============== ============================================================================ ======= ============================ + ============== ============================================================================ ====================================================== ============================ + 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)` + pv-ipi Paravirtualized send IPIs on, off :since:`7.10.0 (QEMU 3.1)` + dirty-ring Enable dirty ring feature on, off; size - must be power of 2, range [1024,65536] :since:`7.10.0 (QEMU 6.1)` + ============== ============================================================================ ====================================================== ============================ ``xen`` Various features to change the behavior of the Xen hypervisor. diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index f01b7a6470..5f9fe3cc58 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -7212,6 +7212,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 552d43b845..6f3c925b55 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, @@ -17589,6 +17590,25 @@ virDomainFeaturesKVMDefParse(virDomainDef *def, def->kvm_features[feature] = value; + /* dirty ring feature should parse size property */ + if (((virDomainKVM) feature == VIR_DOMAIN_KVM_DIRTY_RING) && + (value == VIR_TRISTATE_SWITCH_ON)) { + + if (virXMLPropUInt(node, "size", 0, VIR_XML_PROP_REQUIRED, + &def->dirty_ring_size) < 0) { + return -1; + } + + if ((def->dirty_ring_size != VIR_ROUND_UP_POWER_OF_TWO(def->dirty_ring_size)) || + 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); } @@ -21824,7 +21844,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: @@ -27872,6 +27912,20 @@ 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'", + virDomainKVMTypeToString(j), + virTristateSwitchTypeToString(def->kvm_features[j])); + if (def->dirty_ring_size) { + virBufferAsprintf(&childBuf, " size='%d'/>\n", + def->dirty_ring_size); + } else { + virBufferAddLit(&childBuf, "/>\n"); + } + } + 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 7a185061d8..18a72a79a8 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; } @@ -7280,6 +7283,15 @@ qemuBuildAccelCommandLine(virCommand *cmd, case VIR_DOMAIN_VIRT_KVM: virBufferAddLit(&buf, "kvm"); + /* + * only handle the kvm case, tcg case use the legacy style + * not that either kvm or tcg can be specified by libvirt + * so do not worry about the conflict of specifying both + * */ + 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-ring-size=%d", def->dirty_ring_size); + } break; case VIR_DOMAIN_VIRT_KQEMU: -- 2.27.0