[PATCH Libvirt v3 03/10] libvirt: Add virDomainSetVcpuDirtyLimit API
Daniel P. Berrangé
berrange at redhat.com
Wed Sep 6 11:27:09 UTC 2023
On Tue, Aug 02, 2022 at 10:13:40PM +0800, ~hyman wrote:
> From: Hyman Huang(黄勇) <yong.huang at smartx.com>
>
> 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 at smartx.com>
> ---
> 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);
We've generally tried to avoid adding single purpose APIs for
tunable parameters, instead using APIs with virTypedParameter
arrays to allow bulk updates.
I note that we don't appear to have any mechanism currently
to set the VCPU scheduler tunables either
Perhaps we should have a more general
virDomainSetVCPUTuneParameters(virDomainPtr domain,
int vcpu,
virTypedParameterPtr params,
unsigned int params,
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
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
More information about the libvir-list
mailing list