From: Hyman Huang(黄勇) <huangy81@xxxxxxxxxxxxxxx> Introduce virDomainSetVcpuDirtyLimit API to set upper limit of dirty page rate. Signed-off-by: Hyman Huang(黄勇) <huangy81@xxxxxxxxxxxxxxx> --- include/libvirt/libvirt-domain.h | 16 +++++++++++++ src/driver-hypervisor.h | 7 ++++++ src/libvirt-domain.c | 51 ++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 16 +++++++++++-- src/remote_protocol-structs | 7 ++++++ 7 files changed, 101 insertions(+), 2 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 7430a08..b0bd2f1 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -6452,4 +6452,20 @@ int virDomainStartDirtyRateCalc(virDomainPtr domain, int seconds, unsigned int flags); +/** + * virDomainDirtyLimitFlags: + * + * Since: 8.7.0 + */ +typedef enum { + VIR_DOMAIN_DIRTYLIMIT_VCPU = 0, /* render specified virtual CPU for + dirty page rate limit (Since: 8.7.0) */ + VIR_DOMAIN_DIRTYLIMIT_ALL = 1 << 0, /* render all virtual CPU for dirty + page rate limit (Since: 8.7.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 016d5ce..ac59da6 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1441,6 +1441,12 @@ typedef int int seconds, unsigned int flags); +typedef int +(*virDrvDomainSetVcpuDirtyLimit)(virDomainPtr domain, + int vcpu, + unsigned long long rate, + unsigned int flags); + typedef struct _virHypervisorDriver virHypervisorDriver; /** @@ -1712,4 +1718,5 @@ struct _virHypervisorDriver { virDrvDomainAuthorizedSSHKeysSet domainAuthorizedSSHKeysSet; virDrvDomainGetMessages domainGetMessages; virDrvDomainStartDirtyRateCalc domainStartDirtyRateCalc; + virDrvDomainSetVcpuDirtyLimit domainSetVcpuDirtyLimit; }; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 842663a..be9825b 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -13929,3 +13929,54 @@ virDomainStartDirtyRateCalc(virDomainPtr domain, virDispatchError(conn); return -1; } + +/** + * virDomainSetVcpuDirtyLimit: + * @domain: pointer to domain object, or NULL for Domain0 + * @vcpu: (optional) virtual CPU number + * @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: 8.7.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); + + 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 297a2c4..8ebcf50 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -927,4 +927,9 @@ LIBVIRT_8.5.0 { virDomainAbortJobFlags; } LIBVIRT_8.4.0; +LIBVIRT_8.7.0 { + global: + virDomainSetVcpuDirtyLimit; +} LIBVIRT_8.5.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 0ca365c..f673fed 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8652,6 +8652,7 @@ static virHypervisorDriver hypervisor_driver = { .domainGetMessages = remoteDomainGetMessages, /* 7.1.0 */ .domainStartDirtyRateCalc = remoteDomainStartDirtyRateCalc, /* 7.2.0 */ .domainSetLaunchSecurityState = remoteDomainSetLaunchSecurityState, /* 8.0.0 */ + .domainSetVcpuDirtyLimit = remoteDomainSetVcpuDirtyLimit, /* 8.7.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 79ffc63..e6c18a4 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3921,7 +3921,6 @@ struct remote_domain_start_dirty_rate_calc_args { unsigned int flags; }; - struct remote_domain_event_memory_device_size_change_msg { int callbackID; remote_nonnull_domain dom; @@ -3929,6 +3928,13 @@ struct remote_domain_event_memory_device_size_change_msg { unsigned hyper size; }; +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. */ @@ -6959,5 +6965,11 @@ enum remote_procedure { * @generate: both * @acl: domain:write */ - REMOTE_PROC_DOMAIN_ABORT_JOB_FLAGS = 442 + REMOTE_PROC_DOMAIN_ABORT_JOB_FLAGS = 442, + + /** + * @generate: both + * @acl: domain:write + */ + REMOTE_PROC_DOMAIN_SET_VCPU_DIRTY_LIMIT = 443 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index ca52224..8ff2a86 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -3268,6 +3268,12 @@ struct remote_domain_event_memory_device_size_change_msg { remote_nonnull_string alias; uint64_t size; }; +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, @@ -3711,4 +3717,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_SAVE_PARAMS = 440, REMOTE_PROC_DOMAIN_RESTORE_PARAMS = 441, REMOTE_PROC_DOMAIN_ABORT_JOB_FLAGS = 442, + REMOTE_PROC_DOMAIN_SET_VCPU_DIRTY_LIMIT = 443, }; -- 1.8.3.1