From: Hyman Huang(黄勇) <yong.huang@xxxxxxxxxx> Introduce virDomainSetVcpuDirtyLimit API to set upper limit of dirty page rate. Signed-off-by: Hyman Huang(黄勇) <yong.huang@xxxxxxxxxx> --- include/libvirt/libvirt-domain.h | 16 ++++++++++ src/driver-hypervisor.h | 7 +++++ src/libvirt-domain.c | 54 ++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 ++++++++- src/remote_protocol-structs | 7 +++++ 7 files changed, 104 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index a1902546bb..df7deffaa9 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -6506,4 +6506,20 @@ int virDomainFDAssociate(virDomainPtr domain, int *fds, unsigned int flags); +/** + * virDomainDirtyLimitFlags: + * + * Since: 9.6.0 + */ +typedef enum { + VIR_DOMAIN_DIRTYLIMIT_VCPU = 1 << 0,/* render specified virtual CPU for + dirty page rate upper limit (Since: 9.6.0) */ + VIR_DOMAIN_DIRTYLIMIT_ALL = 1 << 1, /* render all virtual CPU for dirty + page rate upper limit (Since: 9.6.0) */ +} virDomainDirtyLimitFlags; + +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 ec42bb9a53..878d2a6d8c 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -14057,5 +14057,59 @@ virDomainFDAssociate(virDomainPtr domain, error: virDispatchError(conn); +} + +/** + * virDomainSetVcpuDirtyLimit: + * @domain: pointer to domain object, or NULL for Domain0 + * @vcpu: mandatory parameter only if the specified index of the + * virtual CPU is limited; ignored otherwise. + * @rate: upper limit of dirty page rate (MB/s) for virtual CPUs + * @flags: bitwise-OR of supported virDomainDirtyLimitFlags + * + * Dynamically set the upper dirty page rate limit of the virtual CPUs. + * + * Returns 0 in case of success, -1 in case of failure. + * + * Since: 9.6.0 + */ +int +virDomainSetVcpuDirtyLimit(virDomainPtr domain, + int vcpu, + unsigned long long rate, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "vcpu=%d, dirty page rate limit=%lld", + vcpu, rate); + + virCheckFlags(VIR_DOMAIN_DIRTYLIMIT_VCPU | + VIR_DOMAIN_DIRTYLIMIT_ALL, -1); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn = domain->conn; + + virCheckReadOnlyGoto(conn->flags, error); + virCheckPositiveArgGoto(rate, error); + + VIR_EXCLUSIVE_FLAGS_GOTO(VIR_DOMAIN_DIRTYLIMIT_VCPU, + VIR_DOMAIN_DIRTYLIMIT_ALL, + 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 80742f268e..6fc01b518f 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -932,4 +932,9 @@ LIBVIRT_9.0.0 { virDomainFDAssociate; } LIBVIRT_8.5.0; +LIBVIRT_9.6.0 { + global: + virDomainSetVcpuDirtyLimit; +} LIBVIRT_9.0.0; + # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 65ec239fb7..4d7682eb32 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8126,6 +8126,7 @@ static virHypervisorDriver hypervisor_driver = { .domainStartDirtyRateCalc = remoteDomainStartDirtyRateCalc, /* 7.2.0 */ .domainSetLaunchSecurityState = remoteDomainSetLaunchSecurityState, /* 8.0.0 */ .domainFDAssociate = remoteDomainFDAssociate, /* 9.0.0 */ + .domainSetVcpuDirtyLimit = remoteDomainSetVcpuDirtyLimit, /* 9.6.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 5d86a51116..f0b7f0a5fa 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3935,6 +3935,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. */ @@ -6974,5 +6982,10 @@ enum remote_procedure { * @generate: none * @acl: domain:write */ - REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443 + REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443, + /** + * @generate: both + * @acl: domain:write + */ + REMOTE_PROC_DOMAIN_SET_VCPU_DIRTY_LIMIT = 444 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 3c6c230a16..f7543ec667 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -3273,6 +3273,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, @@ -3717,4 +3723,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_RESTORE_PARAMS = 441, REMOTE_PROC_DOMAIN_ABORT_JOB_FLAGS = 442, REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443, + REMOTE_PROC_DOMAIN_SET_VCPU_DIRTY_LIMIT = 444, }; -- 2.38.5