[libvirt] [PATCHv2 1/4] util: Introduce monitor capability interface

John Ferlan jferlan at redhat.com
Tue Sep 18 19:38:44 UTC 2018



On 09/14/2018 09:30 PM, Wang Huaqiang wrote:
> This patch introduces the resource monitor and creates the interface
> for getting host capability of resource monitor from the system resource
> control file system.
> 
> The resource monitor take the role of RDT monitoring group, could be

*takes...

s/, could/ and could/

> used to monitor the resource consumption information, such as the last
> level cache occupancy and the utilization of memory bandwidth.
> 
> Signed-off-by: Wang Huaqiang <huaqiang.wang at intel.com>
> ---
>  src/util/virresctrl.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 124 insertions(+)
> 
> diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
> index 4b5442f..4601f69 100644
> --- a/src/util/virresctrl.c
> +++ b/src/util/virresctrl.c
> @@ -83,6 +83,9 @@ typedef virResctrlInfoPerLevel *virResctrlInfoPerLevelPtr;
>  typedef struct _virResctrlInfoMemBW virResctrlInfoMemBW;
>  typedef virResctrlInfoMemBW *virResctrlInfoMemBWPtr;
>  
> +typedef struct _virResctrlInfoMongrp virResctrlInfoMongrp;
> +typedef virResctrlInfoMongrp *virResctrlInfoMongrpPtr;
> +
>  typedef struct _virResctrlAllocPerType virResctrlAllocPerType;
>  typedef virResctrlAllocPerType *virResctrlAllocPerTypePtr;
>  
> @@ -139,6 +142,28 @@ struct _virResctrlInfoMemBW {
>      unsigned int max_id;
>  };
>  
> +struct _virResctrlInfoMongrp {
> +    /* Maximum number of simultaneous monitors */
> +    unsigned int max_monitor;
> +    /* null-terminal string list for monitor features */
> +    char **features;
> +    /* Number of monitor features */
> +    size_t nfeatures;
> +
> +    /* Last level cache related information */
> +
> +    /* This Adjustable value affects the final reuse of resources used by
> +     * monitor. After the action of removing a monitor, the kernel may not
> +     * release all hardware resources that monitor used immediately if the
> +     * cache occupancy value associated with 'removed' monitor is above this
> +     * threshold. Once the cache occupancy is below this threshold, the
> +     * underlying hardware resource will be reclaimed and be put into the
> +     * resource pool for next reusing.*/
> +    unsigned int cache_reuse_threshold;
> +    /* The cache 'level' that has the monitor capability */
> +    unsigned int cache_level;
> +};
> +
>  struct _virResctrlInfo {
>      virObject parent;
>  
> @@ -146,6 +171,8 @@ struct _virResctrlInfo {
>      size_t nlevels;
>  
>      virResctrlInfoMemBWPtr membw_info;
> +
> +    virResctrlInfoMongrpPtr monitor_info;
>  };
>  
>  
> @@ -171,8 +198,12 @@ virResctrlInfoDispose(void *obj)
>          VIR_FREE(level);
>      }
>  
> +    if (resctrl->monitor_info)
> +        VIR_FREE(resctrl->monitor_info->features);

virStringListFree

> +
>      VIR_FREE(resctrl->membw_info);
>      VIR_FREE(resctrl->levels);
> +    VIR_FREE(resctrl->monitor_info);
>  }
>  
>  
> @@ -555,6 +586,92 @@ virResctrlGetMemoryBandwidthInfo(virResctrlInfoPtr resctrl)
>  }
>  
>  
> +/*
> + * Retrieve monitor capability from the resource control file system.
> + *
> + * The monitor capability is exposed through "SYSFS_RESCTRL_PATH/info/L3_MON"
> + * directory under the resource control file system. The monitor capability is
> + * parsed by reading the interface files and stored in the structure
> + * 'virResctrlInfoMongrp'.
> + *
> + * Not all host supports the resource monitor, leave the pointer
> + * @resctrl->monitor_info empty if not supported.
> + */
> +static int
> +virResctrlGetMonitorInfo(virResctrlInfoPtr resctrl)
> +{
> +    int ret = -1;
> +    int rv = -1;
> +    char *featurestr = NULL;
> +    char **features = NULL;
> +    size_t nfeatures = 0;
> +    virResctrlInfoMongrpPtr info_monitor = NULL;
> +
> +    if (VIR_ALLOC(info_monitor) < 0)
> +        return -1;
> +
> +    /* monitor only exists in leve 3 cache */

*level

Let's say, "For now, monitor only exists in level 3 cache"

> +    info_monitor->cache_level = 3;

So I think in the last review I was thinking that if we ever see a
different level, then the L3 below would need to change. Although for
now I wonder if it should be removed. I'll leave it unless you really
think it should be removed. I think I was being ultra careful/paranoid.

Perhaps the future is GetMonitorInfo takes in the cache_level as a
parameter in order to build up the path and save the level in a
structure.  I think to a degree we're good to have that level of
indirection with these latest changes.  I don't mind removing it
completely from this pile, but don't want to mess you up for the future
either!

> +
> +    rv = virFileReadValueUint(&info_monitor->max_monitor,
> +                              SYSFS_RESCTRL_PATH "/info/L3_MON/num_rmids");
> +    if (rv == -2) {
> +        /* The file doesn't exist, so it's unusable for us, probably resource
> +         * monitor unsupported */
> +        VIR_INFO("The path '" SYSFS_RESCTRL_PATH "/info/L3_MON/num_rmids' "
> +                 "does not exist");

Add virResetLastError()

[avoids having this error in Last and something else failing and spewing
the error]

> +        ret = 0;
> +        goto cleanup;
> +    } else if (rv < 0) {
> +        /* Other failures are fatal, so just quit */
> +        goto cleanup;
> +    }
> +
> +    rv = virFileReadValueUint(&info_monitor->cache_reuse_threshold,
> +                              SYSFS_RESCTRL_PATH
> +                              "/info/L3_MON/max_threshold_occupancy");
> +    if (rv == -2) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("Cannot get max_threshold_occupancy from resctrl"
> +                         " info"));

Typically the extra space is on the previous line.  I'm just going to
remove the " info" completely... Also adding ' ' around the variable
name searched on.  Something I'll repeat for subsequent messages.

> +    }
> +    if (rv < 0)
> +        goto cleanup;
> +
> +    rv = virFileReadValueString(&featurestr,
> +                                SYSFS_RESCTRL_PATH
> +                                "/info/L3_MON/mon_features");
> +    if (rv == -2)
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("Cannot get mon_features from resctrl info"));
> +    if (rv < 0)
> +        goto cleanup;
> +
> +    if (!featurestr) {

I don't think !featurestr could happen as a result of the following in
virFileReadLimFD (which is is in the call path):

    s = saferead_lim(fd, maxlen+1, &len);
    if (s == NULL)
        return -1;
...
    *buf = s;
    return len;

Thus if s = NULL, then we return -1; otherwise, *buf = s or @featurestr
= s, meaning no chance NULL is set without -1 being returned.

I think you meant:

    "if (!*featurestr)"

considering the subsequent lines...

> +        /* if no feature found in "/info/L3_MON/mon_features",
> +         * some error happens */
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("Cannot get feature list from resctrl info"));

Thus this is "Found empty feature list from resctrl"

> +        ret  = -1;

This is unnecessary since @ret ==  -1 at this point... @rv could be 0,
but we don't care. FWIW: one too many spaces between ret and =.


I can clean all this up - just let me know that the !*featurestr check
is what you after....

Reviewed-by: John Ferlan <jferlan at redhat.com>

John

> +        goto cleanup;
> +    }
> +
> +    features = virStringSplitCount(featurestr, "\n", 0, &nfeatures);
> +    VIR_DEBUG("Resctrl supported %ld monitoring features", nfeatures);
> +
> +    info_monitor->nfeatures = nfeatures;
> +    VIR_STEAL_PTR(info_monitor->features, features);
> +    VIR_STEAL_PTR(resctrl->monitor_info, info_monitor);
> +
> +    ret = 0;
> + cleanup:
> +    VIR_FREE(featurestr);
> +    virStringListFree(features);
> +    VIR_FREE(info_monitor);
> +    return ret;
> +}
> +
> +
>  static int
>  virResctrlGetInfo(virResctrlInfoPtr resctrl)
>  {
> @@ -573,6 +690,10 @@ virResctrlGetInfo(virResctrlInfoPtr resctrl)
>      if (ret < 0)
>          goto cleanup;
>  
> +    ret = virResctrlGetMonitorInfo(resctrl);
> +    if (ret < 0)
> +        goto cleanup;
> +
>      ret = 0;
>   cleanup:
>      VIR_DIR_CLOSE(dirp);
> @@ -613,6 +734,9 @@ virResctrlInfoIsEmpty(virResctrlInfoPtr resctrl)
>      if (resctrl->membw_info)
>          return false;
>  
> +    if (resctrl->monitor_info)
> +        return false;
> +
>      for (i = 0; i < resctrl->nlevels; i++) {
>          virResctrlInfoPerLevelPtr i_level = resctrl->levels[i];
>  
> 




More information about the libvir-list mailing list