On Tue, Aug 02, 2022 at 10:13:40PM +0800, ~hyman wrote:
> From: Hyman Huang(黄勇) <yong.hu...@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.hu...@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 :|

Reply via email to