util: Add MBA capability information query to resctrl

Introducing virResctrlInfoMemBW for the information memory bandwidth
allocation information.

Signed-off-by: Bing Niu <bing.niu@intel.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Bing Niu 2018-07-30 11:12:28 +08:00 committed by John Ferlan
parent 65bae2f18c
commit a24da791b8

View File

@ -80,6 +80,9 @@ typedef virResctrlInfoPerType *virResctrlInfoPerTypePtr;
typedef struct _virResctrlInfoPerLevel virResctrlInfoPerLevel;
typedef virResctrlInfoPerLevel *virResctrlInfoPerLevelPtr;
typedef struct _virResctrlInfoMemBW virResctrlInfoMemBW;
typedef virResctrlInfoMemBW *virResctrlInfoMemBWPtr;
typedef struct _virResctrlAllocPerType virResctrlAllocPerType;
typedef virResctrlAllocPerType *virResctrlAllocPerTypePtr;
@ -116,11 +119,30 @@ struct _virResctrlInfoPerLevel {
virResctrlInfoPerTypePtr *types;
};
/* Information about memory bandwidth allocation */
struct _virResctrlInfoMemBW {
/* minimum memory bandwidth allowed */
unsigned int min_bandwidth;
/* bandwidth granularity */
unsigned int bandwidth_granularity;
/* Maximum number of simultaneous allocations */
unsigned int max_allocation;
/* level number of last level cache */
unsigned int last_level_cache;
/* max id of last level cache, this is used to track
* how many last level cache available in host system,
* the number of memory bandwidth allocation controller
* is identical with last level cache. */
unsigned int max_id;
};
struct _virResctrlInfo {
virObject parent;
virResctrlInfoPerLevelPtr *levels;
size_t nlevels;
virResctrlInfoMemBWPtr membw_info;
};
@ -146,6 +168,7 @@ virResctrlInfoDispose(void *obj)
VIR_FREE(level);
}
VIR_FREE(resctrl->membw_info);
VIR_FREE(resctrl->levels);
}
@ -442,6 +465,60 @@ virResctrlGetCacheInfo(virResctrlInfoPtr resctrl,
}
static int
virResctrlGetMemoryBandwidthInfo(virResctrlInfoPtr resctrl)
{
int ret = -1;
int rv = -1;
virResctrlInfoMemBWPtr i_membw = NULL;
/* query memory bandwidth allocation info */
if (VIR_ALLOC(i_membw) < 0)
goto cleanup;
rv = virFileReadValueUint(&i_membw->bandwidth_granularity,
SYSFS_RESCTRL_PATH "/info/MB/bandwidth_gran");
if (rv == -2) {
/* The file doesn't exist, so it's unusable for us,
* probably memory bandwidth allocation unsupported */
VIR_INFO("The path '" SYSFS_RESCTRL_PATH "/info/MB/bandwidth_gran'"
"does not exist");
ret = 0;
goto cleanup;
} else if (rv < 0) {
/* Other failures are fatal, so just quit */
goto cleanup;
}
rv = virFileReadValueUint(&i_membw->min_bandwidth,
SYSFS_RESCTRL_PATH "/info/MB/min_bandwidth");
if (rv == -2) {
/* If the previous file exists, so should this one. Hence -2 is
* fatal in this case (errors out in next condition) - the kernel
* interface might've changed too much or something else is wrong. */
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot get min bandwidth from resctrl memory info"));
}
if (rv < 0)
goto cleanup;
rv = virFileReadValueUint(&i_membw->max_allocation,
SYSFS_RESCTRL_PATH "/info/MB/num_closids");
if (rv == -2) {
/* Similar reasoning to min_bandwidth above. */
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot get max allocation from resctrl memory info"));
}
if (rv < 0)
goto cleanup;
VIR_STEAL_PTR(resctrl->membw_info, i_membw);
ret = 0;
cleanup:
VIR_FREE(i_membw);
return ret;
}
static int
virResctrlGetInfo(virResctrlInfoPtr resctrl)
{
@ -452,6 +529,10 @@ virResctrlGetInfo(virResctrlInfoPtr resctrl)
if (ret <= 0)
goto cleanup;
ret = virResctrlGetMemoryBandwidthInfo(resctrl);
if (ret < 0)
goto cleanup;
ret = virResctrlGetCacheInfo(resctrl, dirp);
if (ret < 0)
goto cleanup;
@ -493,6 +574,9 @@ virResctrlInfoIsEmpty(virResctrlInfoPtr resctrl)
if (!resctrl)
return true;
if (resctrl->membw_info)
return false;
for (i = 0; i < resctrl->nlevels; i++) {
virResctrlInfoPerLevelPtr i_level = resctrl->levels[i];