[PATCH Libvirt v3 03/10] libvirt: Add virDomainSetVcpuDirtyLimit API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hyman Huang(黄勇) <yong.huang@xxxxxxxxxx>

Introduce virDomainSetVcpuDirtyLimit API to set or cancel the
dirty page rate upper limit.

The API will throttle the virtual CPU as needed to keep their dirty
page rate within the limit. Since it just throttles the virtual CPU,
which dirties memory, read processes in the guest OS aren't penalized.

The feature therefor could, in some scenes, be used to provide
quality-of-service in the aspect of the memory workload for virtual
CPUs.

Signed-off-by: Hyman Huang(黄勇) <yong.huang@xxxxxxxxxx>
---
 include/libvirt/libvirt-domain.h |  4 +++
 src/driver-hypervisor.h          |  7 ++++
 src/libvirt-domain.c             | 59 ++++++++++++++++++++++++++++++++
 src/libvirt_public.syms          |  1 +
 src/remote/remote_driver.c       |  1 +
 src/remote/remote_protocol.x     | 18 +++++++++-
 src/remote_protocol-structs      |  7 ++++
 7 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index a1902546bb..3d3c7cdcba 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -6506,4 +6506,8 @@ int virDomainFDAssociate(virDomainPtr domain,
                          int *fds,
                          unsigned int flags);
 
+int virDomainSetVcpuDirtyLimit(virDomainPtr domain,
+                               int vcpu,
+                               unsigned long long rate,
+                               unsigned int flags);
 #endif /* LIBVIRT_DOMAIN_H */
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 5219344b72..e61b9efca5 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1448,6 +1448,12 @@ typedef int
                            int *fds,
                            unsigned int flags);
 
+typedef int
+(*virDrvDomainSetVcpuDirtyLimit)(virDomainPtr domain,
+                                 int vcpu,
+                                 unsigned long long rate,
+                                 unsigned int flags);
+
 typedef struct _virHypervisorDriver virHypervisorDriver;
 
 /**
@@ -1720,4 +1726,5 @@ struct _virHypervisorDriver {
     virDrvDomainGetMessages domainGetMessages;
     virDrvDomainStartDirtyRateCalc domainStartDirtyRateCalc;
     virDrvDomainFDAssociate domainFDAssociate;
+    virDrvDomainSetVcpuDirtyLimit domainSetVcpuDirtyLimit;
 };
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 6616294fc1..5b505cc519 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -14041,3 +14041,62 @@ virDomainFDAssociate(virDomainPtr domain,
     virDispatchError(conn);
     return -1;
 }
+
+/**
+ * virDomainSetVcpuDirtyLimit:
+ * @domain: pointer to domain object
+ * @vcpu: index of the limited virtual CPU
+ * @rate: upper limit of dirty page rate (mebibyte/s) for virtual CPUs
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Dynamically set the dirty page rate upper limit for the virtual CPUs.
+ *
+ * @vcpu may be a positive value, zero, or equal to -1. If -1 is set,
+ * the change affects all virtual CPUs of VM; it affects the specified
+ * virtual CPU otherwise.
+ * @rate may be 0 to cancel the limit or a positive value to enable. The
+ * hypervisors are free to round it down to the nearest mebibyte/s.
+ *
+ * The API will throttle the virtual CPU as needed to keep their dirty
+ * page rate within the limit set by @rate. Since it just throttles the
+ * virtual CPU, which dirties memory, read processes in the guest OS
+ * aren't penalized. This could, in some scenes, be used to provide
+ * quality-of-service in the aspect of the memory workload for virtual
+ * CPUs.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ *
+ * Since: 9.7.0
+ */
+int
+virDomainSetVcpuDirtyLimit(virDomainPtr domain,
+                           int vcpu,
+                           unsigned long long rate,
+                           unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(domain, "vcpu=%d, rate=%llu, flags=0x%x",
+                     vcpu, rate, flags);
+
+    virResetLastError();
+
+    virCheckDomainReturn(domain, -1);
+    conn = domain->conn;
+
+    virCheckReadOnlyGoto(conn->flags, error);
+
+    if (conn->driver->domainSetVcpuDirtyLimit) {
+        int ret;
+        ret = conn->driver->domainSetVcpuDirtyLimit(domain, vcpu, rate, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(domain->conn);
+    return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index bd1e916d2a..602494935d 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -934,6 +934,7 @@ LIBVIRT_9.0.0 {
 
 LIBVIRT_9.7.0 {
     global:
+        virDomainSetVcpuDirtyLimit;
         virNetworkGetMetadata;
         virNetworkSetMetadata;
 } LIBVIRT_9.0.0;
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 0b925f8edc..15d023154b 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8110,6 +8110,7 @@ static virHypervisorDriver hypervisor_driver = {
     .domainStartDirtyRateCalc = remoteDomainStartDirtyRateCalc, /* 7.2.0 */
     .domainSetLaunchSecurityState = remoteDomainSetLaunchSecurityState, /* 8.0.0 */
     .domainFDAssociate = remoteDomainFDAssociate, /* 9.0.0 */
+    .domainSetVcpuDirtyLimit = remoteDomainSetVcpuDirtyLimit, /* 9.7.0 */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 7ff059e393..72b2684912 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3955,6 +3955,14 @@ struct remote_domain_fd_associate_args {
     remote_nonnull_string name;
     unsigned int flags;
 };
+
+struct remote_domain_set_vcpu_dirty_limit_args {
+    remote_nonnull_domain dom;
+    int vcpu;
+    unsigned hyper rate;
+    unsigned int flags;
+};
+
 /*----- Protocol. -----*/
 
 /* Define the program number, protocol version and procedure numbers here. */
@@ -7008,5 +7016,13 @@ enum remote_procedure {
      * @generate: both
      * @acl: network:read
      */
-    REMOTE_PROC_NETWORK_GET_METADATA = 445
+    REMOTE_PROC_NETWORK_GET_METADATA = 445,
+
+    /**
+     * @generate: both
+     * @acl: domain:write
+     * @acl: domain:save:!VIR_DOMAIN_AFFECT_CONFIG|VIR_DOMAIN_AFFECT_LIVE
+     * @acl: domain:save:VIR_DOMAIN_AFFECT_CONFIG
+     */
+    REMOTE_PROC_DOMAIN_SET_VCPU_DIRTY_LIMIT = 446
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index c07e0af1e6..715a121f36 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -3290,6 +3290,12 @@ struct remote_domain_fd_associate_args {
         remote_nonnull_string      name;
         u_int                      flags;
 };
+struct remote_domain_set_vcpu_dirty_limit_args {
+        remote_nonnull_domain      dom;
+        int                        vcpu;
+        uint64_t                   rate;
+        u_int                      flags;
+};
 enum remote_procedure {
         REMOTE_PROC_CONNECT_OPEN = 1,
         REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3736,4 +3742,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443,
         REMOTE_PROC_NETWORK_SET_METADATA = 444,
         REMOTE_PROC_NETWORK_GET_METADATA = 445,
+        REMOTE_PROC_DOMAIN_SET_VCPU_DIRTY_LIMIT = 446,
 };
-- 
2.38.5





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux