From: Hyman Huang(黄勇) <yong.huang(a)smartx.com>
Implement qemuDomainSetVcpuDirtyLimit which set dirty page
rate upper limit.
Signed-off-by: Hyman Huang(黄勇) <yong.huang(a)smartx.com>
---
src/qemu/qemu_driver.c | 52 ++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor.c | 13 +++++++++
src/qemu/qemu_monitor.h | 5 ++++
src/qemu/qemu_monitor_json.c | 45 +++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 5 ++++
5 files changed, 120 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 497923ffee..61b992fc51 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19912,6 +19912,57 @@ qemuDomainFDAssociate(virDomainPtr domain,
return ret;
}
+static int
+qemuDomainSetVcpuDirtyLimit(virDomainPtr domain,
+ int vcpu,
+ unsigned long long rate,
+ unsigned int flags)
+{
+ virDomainObj *vm = NULL;
+ qemuDomainObjPrivate *priv;
+ int ret = -1;
+
+ if (!(vm = qemuDomainObjFromDomain(domain)))
+ return -1;
+
+ if (virDomainSetVcpuDirtyLimitEnsureACL(domain->conn, vm->def))
+ goto cleanup;
+
+ priv = vm->privateData;
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VCPU_DIRTY_LIMIT)) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("QEMU does not support setting dirty page rate
limit"));
+ goto cleanup;
+ }
+
+ if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (virDomainObjCheckActive(vm) < 0)
+ goto endjob;
+
+ qemuDomainObjEnterMonitor(vm);
+ if (flags & VIR_DOMAIN_DIRTYLIMIT_VCPU) {
+ if (vcpu < 0) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("Require cpu index to limit dirty page rate"));
+ goto endjob;
+ }
+ ret = qemuMonitorSetVcpuDirtyLimit(priv->mon, vcpu, rate);
+ VIR_DEBUG("Set vcpu[%d] dirty page rate limit %lld", vcpu, rate);
+ } else {
+ ret = qemuMonitorSetVcpuDirtyLimit(priv->mon, -1, rate);
+ VIR_DEBUG("Set all vcpus dirty page rate limit %lld of vm", rate);
+ }
+ qemuDomainObjExitMonitor(vm);
+
+ endjob:
+ virDomainObjEndJob(vm);
+
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ return ret;
+}
static virHypervisorDriver qemuHypervisorDriver = {
.name = QEMU_DRIVER_NAME,
@@ -20162,6 +20213,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainStartDirtyRateCalc = qemuDomainStartDirtyRateCalc, /* 7.2.0 */
.domainSetLaunchSecurityState = qemuDomainSetLaunchSecurityState, /* 8.0.0 */
.domainFDAssociate = qemuDomainFDAssociate, /* 9.0.0 */
+ .domainSetVcpuDirtyLimit = qemuDomainSetVcpuDirtyLimit, /* 9.6.0 */
};
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index c680c4b804..87926edec6 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4505,3 +4505,16 @@ qemuMonitorGetStatsByQOMPath(virJSONValue *arr,
return NULL;
}
+
+
+int
+qemuMonitorSetVcpuDirtyLimit(qemuMonitor *mon,
+ int vcpu,
+ unsigned long long rate)
+{
+ VIR_DEBUG("set vcpu %d dirty page rate limit %lld", vcpu, rate);
+
+ QEMU_CHECK_MONITOR(mon);
+
+ return qemuMonitorJSONSetVcpuDirtyLimit(mon, vcpu, rate);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 6c590933aa..07a05365cf 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1579,3 +1579,8 @@ qemuMonitorExtractQueryStats(virJSONValue *info);
virJSONValue *
qemuMonitorGetStatsByQOMPath(virJSONValue *arr,
char *qom_path);
+
+int
+qemuMonitorSetVcpuDirtyLimit(qemuMonitor *mon,
+ int vcpu,
+ unsigned long long rate);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index d9e9a4481c..732366ab29 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8889,3 +8889,48 @@ qemuMonitorJSONQueryStats(qemuMonitor *mon,
return virJSONValueObjectStealArray(reply, "return");
}
+
+/**
+ * qemuMonitorJSONSetVcpuDirtyLimit:
+ * @mon: monitor object
+ * @vcpu: virtual cpu index to be set, -1 means all virtual cpus
+ * @rate: dirty page rate upper limit to be set
+ *
+ * Returns -1 on failure.
+ */
+int
+qemuMonitorJSONSetVcpuDirtyLimit(qemuMonitor *mon,
+ int vcpu,
+ unsigned long long rate)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+
+ if (vcpu < -1)
+ return -1;
+
+ if (vcpu >= 0) {
+ /* set vcpu dirty page rate limit */
+ if (!(cmd = qemuMonitorJSONMakeCommand("set-vcpu-dirty-limit",
+ "i:cpu-index", vcpu,
+ "U:dirty-rate", rate,
+ NULL))) {
+ return -1;
+ }
+ } else if (vcpu == -1) {
+ /* set vm dirty page rate limit */
+ if (!(cmd = qemuMonitorJSONMakeCommand("set-vcpu-dirty-limit",
+ "U:dirty-rate", rate,
+ NULL))) {
+ return -1;
+ }
+ }
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ return -1;
+
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ return -1;
+
+ return 0;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 06023b98ea..89f61b3052 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -825,3 +825,8 @@ qemuMonitorJSONQueryStats(qemuMonitor *mon,
qemuMonitorQueryStatsTargetType target,
char **vcpus,
GPtrArray *providers);
+
+int
+qemuMonitorJSONSetVcpuDirtyLimit(qemuMonitor *mon,
+ int vcpu,
+ unsigned long long rate);
--
2.38.5