255 lines
9.2 KiB
Diff
255 lines
9.2 KiB
Diff
|
|
From 24a179c25897dbfaa015ff62940648877d9d50ef Mon Sep 17 00:00:00 2001
|
||
|
|
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
|
||
|
|
<huangy81@chinatelecom.cn>
|
||
|
|
Date: Tue, 23 Nov 2021 09:36:58 -0500
|
||
|
|
Subject: [PATCH] qemu: support dirty ring feature
|
||
|
|
MIME-Version: 1.0
|
||
|
|
Content-Type: text/plain; charset=UTF-8
|
||
|
|
Content-Transfer-Encoding: 8bit
|
||
|
|
|
||
|
|
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>
|
||
|
|
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
|
||
|
|
---
|
||
|
|
docs/formatdomain.html.in | 7 ++++
|
||
|
|
docs/schemas/domaincommon.rng | 10 +++++
|
||
|
|
src/conf/domain_conf.c | 42 +++++++++++++++++++
|
||
|
|
src/conf/domain_conf.h | 3 ++
|
||
|
|
src/qemu/qemu_command.c | 3 ++
|
||
|
|
tests/qemuxml2argvdata/kvm-features-off.xml | 1 +
|
||
|
|
tests/qemuxml2argvdata/kvm-features.xml | 1 +
|
||
|
|
tests/qemuxml2xmloutdata/kvm-features-off.xml | 1 +
|
||
|
|
tests/qemuxml2xmloutdata/kvm-features.xml | 1 +
|
||
|
|
9 files changed, 69 insertions(+)
|
||
|
|
|
||
|
|
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
|
||
|
|
index 6e51c3bac9..0521a847d8 100644
|
||
|
|
--- a/docs/formatdomain.html.in
|
||
|
|
+++ b/docs/formatdomain.html.in
|
||
|
|
@@ -2055,6 +2055,7 @@
|
||
|
|
<kvm>
|
||
|
|
<hidden state='on'/>
|
||
|
|
<hint-dedicated state='on'/>
|
||
|
|
+ <dirty-ring state='on' size='4096'/>
|
||
|
|
</kvm>
|
||
|
|
<pvspinlock state='on'/>
|
||
|
|
<gic version='2'/>
|
||
|
|
@@ -2235,6 +2236,12 @@
|
||
|
|
<td>on, off</td>
|
||
|
|
<td><span class="since">5.7.0 (QEMU 2.12.0)</span></td>
|
||
|
|
</tr>
|
||
|
|
+ <tr>
|
||
|
|
+ <td>dirty-ring</td>
|
||
|
|
+ <td>Enable dirty ring feature</td>
|
||
|
|
+ <td>on, off; size - must be power of 2, range [1024,65536]</td>
|
||
|
|
+ <td><span class="since">8.0.0 (QEMU 6.1)</span></td>
|
||
|
|
+ </tr>
|
||
|
|
</table>
|
||
|
|
</dd>
|
||
|
|
<dt><code>pmu</code></dt>
|
||
|
|
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
|
||
|
|
index 764f826df4..e3b51d333c 100644
|
||
|
|
--- a/docs/schemas/domaincommon.rng
|
||
|
|
+++ b/docs/schemas/domaincommon.rng
|
||
|
|
@@ -6327,6 +6327,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 e94ae4ea17..cf807c7747 100644
|
||
|
|
--- a/src/conf/domain_conf.c
|
||
|
|
+++ b/src/conf/domain_conf.c
|
||
|
|
@@ -205,6 +205,7 @@ VIR_ENUM_IMPL(virDomainKVM,
|
||
|
|
VIR_DOMAIN_KVM_LAST,
|
||
|
|
"hidden",
|
||
|
|
"hint-dedicated",
|
||
|
|
+ "dirty-ring",
|
||
|
|
);
|
||
|
|
|
||
|
|
VIR_ENUM_IMPL(virDomainMsrsUnknown,
|
||
|
|
@@ -20620,6 +20621,22 @@ 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);
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -23590,6 +23607,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
|
||
|
|
switch ((virDomainKVM) i) {
|
||
|
|
case VIR_DOMAIN_KVM_HIDDEN:
|
||
|
|
case VIR_DOMAIN_KVM_DEDICATED:
|
||
|
|
+ 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: "
|
||
|
|
@@ -23607,6 +23625,16 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr 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 */
|
||
|
|
@@ -29214,6 +29242,20 @@ virDomainDefFormatFeatures(virBufferPtr 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;
|
||
|
|
+
|
||
|
|
/* 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 d75d06d7b8..7419bf8d7e 100644
|
||
|
|
--- a/src/conf/domain_conf.h
|
||
|
|
+++ b/src/conf/domain_conf.h
|
||
|
|
@@ -1840,6 +1840,7 @@ typedef enum {
|
||
|
|
typedef enum {
|
||
|
|
VIR_DOMAIN_KVM_HIDDEN = 0,
|
||
|
|
VIR_DOMAIN_KVM_DEDICATED,
|
||
|
|
+ VIR_DOMAIN_KVM_DIRTY_RING,
|
||
|
|
|
||
|
|
VIR_DOMAIN_KVM_LAST
|
||
|
|
} virDomainKVM;
|
||
|
|
@@ -2300,6 +2301,8 @@ struct _virDomainResctrlDef {
|
||
|
|
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 */
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
||
|
|
index ed843315dc..b879f7f39a 100644
|
||
|
|
--- a/src/qemu/qemu_command.c
|
||
|
|
+++ b/src/qemu/qemu_command.c
|
||
|
|
@@ -6920,6 +6920,9 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
|
||
|
|
virBufferAddLit(&buf, ",kvm-hint-dedicated=on");
|
||
|
|
break;
|
||
|
|
|
||
|
|
+ case VIR_DOMAIN_KVM_DIRTY_RING:
|
||
|
|
+ break;
|
||
|
|
+
|
||
|
|
/* coverity[dead_error_begin] */
|
||
|
|
case VIR_DOMAIN_KVM_LAST:
|
||
|
|
break;
|
||
|
|
diff --git a/tests/qemuxml2argvdata/kvm-features-off.xml b/tests/qemuxml2argvdata/kvm-features-off.xml
|
||
|
|
index 21d492c8b9..f53e31db6b 100644
|
||
|
|
--- a/tests/qemuxml2argvdata/kvm-features-off.xml
|
||
|
|
+++ b/tests/qemuxml2argvdata/kvm-features-off.xml
|
||
|
|
@@ -13,6 +13,7 @@
|
||
|
|
<kvm>
|
||
|
|
<hidden state='off'/>
|
||
|
|
<hint-dedicated state='off'/>
|
||
|
|
+ <dirty-ring state='off'/>
|
||
|
|
</kvm>
|
||
|
|
</features>
|
||
|
|
<clock offset='utc'/>
|
||
|
|
diff --git a/tests/qemuxml2argvdata/kvm-features.xml b/tests/qemuxml2argvdata/kvm-features.xml
|
||
|
|
index 85f74786c9..fd08a7a0f5 100644
|
||
|
|
--- a/tests/qemuxml2argvdata/kvm-features.xml
|
||
|
|
+++ b/tests/qemuxml2argvdata/kvm-features.xml
|
||
|
|
@@ -13,6 +13,7 @@
|
||
|
|
<kvm>
|
||
|
|
<hidden state='on'/>
|
||
|
|
<hint-dedicated state='on'/>
|
||
|
|
+ <dirty-ring state='on' size='4096'/>
|
||
|
|
</kvm>
|
||
|
|
</features>
|
||
|
|
<cpu mode='host-passthrough' check='none'/>
|
||
|
|
diff --git a/tests/qemuxml2xmloutdata/kvm-features-off.xml b/tests/qemuxml2xmloutdata/kvm-features-off.xml
|
||
|
|
index 9068be3e7b..2c8b6a81d3 100644
|
||
|
|
--- a/tests/qemuxml2xmloutdata/kvm-features-off.xml
|
||
|
|
+++ b/tests/qemuxml2xmloutdata/kvm-features-off.xml
|
||
|
|
@@ -13,6 +13,7 @@
|
||
|
|
<kvm>
|
||
|
|
<hidden state='off'/>
|
||
|
|
<hint-dedicated state='off'/>
|
||
|
|
+ <dirty-ring state='off'/>
|
||
|
|
</kvm>
|
||
|
|
</features>
|
||
|
|
<clock offset='utc'/>
|
||
|
|
diff --git a/tests/qemuxml2xmloutdata/kvm-features.xml b/tests/qemuxml2xmloutdata/kvm-features.xml
|
||
|
|
index 7c554671b3..6e97065fed 100644
|
||
|
|
--- a/tests/qemuxml2xmloutdata/kvm-features.xml
|
||
|
|
+++ b/tests/qemuxml2xmloutdata/kvm-features.xml
|
||
|
|
@@ -13,6 +13,7 @@
|
||
|
|
<kvm>
|
||
|
|
<hidden state='on'/>
|
||
|
|
<hint-dedicated state='on'/>
|
||
|
|
+ <dirty-ring state='on' size='4096'/>
|
||
|
|
</kvm>
|
||
|
|
</features>
|
||
|
|
<cpu mode='host-passthrough' check='none'/>
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|