qemu: support dirty ring feature

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 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@chinatelecom.cn>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Hyman Huang(黄勇) 2021-11-23 09:36:58 -05:00 committed by Michal Privoznik
parent a8e0f9c682
commit 5d18d740d8
9 changed files with 75 additions and 8 deletions

View File

@ -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'/>
@ -1928,14 +1929,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:`8.0.0 (QEMU 6.1)`
============== ============================================================================ ====================================================== ============================
``xen``
Various features to change the behavior of the Xen hypervisor.

View File

@ -7225,6 +7225,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>

View File

@ -206,6 +206,7 @@ VIR_ENUM_IMPL(virDomainKVM,
"hint-dedicated",
"poll-control",
"pv-ipi",
"dirty-ring",
);
VIR_ENUM_IMPL(virDomainXen,
@ -17556,6 +17557,25 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
kvm->features[feature] = value;
/* dirty ring feature should parse size property */
if (feature == VIR_DOMAIN_KVM_DIRTY_RING &&
value == VIR_TRISTATE_SWITCH_ON) {
if (virXMLPropUInt(node, "size", 0, VIR_XML_PROP_REQUIRED,
&kvm->dirty_ring_size) < 0) {
return -1;
}
if (!VIR_IS_POW2(kvm->dirty_ring_size) ||
kvm->dirty_ring_size < 1024 ||
kvm->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);
}
@ -21809,6 +21829,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
case VIR_DOMAIN_KVM_DEDICATED:
case VIR_DOMAIN_KVM_POLLCONTROL:
case VIR_DOMAIN_KVM_PVIPI:
case VIR_DOMAIN_KVM_DIRTY_RING:
if (src->kvm_features->features[i] != dst->kvm_features->features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of KVM feature '%s' differs: "
@ -21825,6 +21846,16 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
break;
}
}
if (src->kvm_features->dirty_ring_size != dst->kvm_features->dirty_ring_size) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("dirty ring size of KVM feature '%s' differs: "
"source: '%d', destination: '%d'"),
virDomainKVMTypeToString(i),
src->kvm_features->dirty_ring_size,
dst->kvm_features->dirty_ring_size);
return false;
}
}
/* smm */
@ -27886,6 +27917,20 @@ virDomainDefFormatFeatures(virBuffer *buf,
def->kvm_features->features[j]));
break;
case VIR_DOMAIN_KVM_DIRTY_RING:
if (def->kvm_features->features[j] != VIR_TRISTATE_SWITCH_ABSENT) {
virBufferAsprintf(&childBuf, "<%s state='%s'",
virDomainKVMTypeToString(j),
virTristateSwitchTypeToString(def->kvm_features->features[j]));
if (def->kvm_features->dirty_ring_size > 0) {
virBufferAsprintf(&childBuf, " size='%d'/>\n",
def->kvm_features->dirty_ring_size);
} else {
virBufferAddLit(&childBuf, "/>\n");
}
}
break;
case VIR_DOMAIN_KVM_LAST:
break;
}

View File

@ -2085,6 +2085,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;
@ -2266,6 +2267,8 @@ VIR_ENUM_DECL(virDomainIBS);
typedef struct _virDomainFeatureKVM virDomainFeatureKVM;
struct _virDomainFeatureKVM {
int features[VIR_DOMAIN_KVM_LAST];
unsigned int dirty_ring_size; /* size of dirty ring for each vCPU, no units */
};
typedef struct _virDomainFeatureTCG virDomainFeatureTCG;

View File

@ -6784,6 +6784,9 @@ qemuBuildCpuCommandLine(virCommand *cmd,
virBufferAddLit(&buf, ",kvm-pv-ipi=off");
break;
case VIR_DOMAIN_KVM_DIRTY_RING:
break;
case VIR_DOMAIN_KVM_LAST:
break;
}

View File

@ -15,6 +15,7 @@
<hint-dedicated state='off'/>
<poll-control state='off'/>
<pv-ipi state='off'/>
<dirty-ring state='off'/>
</kvm>
</features>
<cpu mode='host-passthrough' check='none'/>

View File

@ -15,6 +15,7 @@
<hint-dedicated state='on'/>
<poll-control state='on'/>
<pv-ipi state='on'/>
<dirty-ring state='on' size='4096'/>
</kvm>
</features>
<cpu mode='host-passthrough' check='none'/>

View File

@ -15,6 +15,7 @@
<hint-dedicated state='off'/>
<poll-control state='off'/>
<pv-ipi state='off'/>
<dirty-ring state='off'/>
</kvm>
</features>
<cpu mode='host-passthrough' check='none' migratable='off'/>

View File

@ -15,6 +15,7 @@
<hint-dedicated state='on'/>
<poll-control state='on'/>
<pv-ipi state='on'/>
<dirty-ring state='on' size='4096'/>
</kvm>
</features>
<cpu mode='host-passthrough' check='none' migratable='off'/>