mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 06:05:27 +00:00
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:
parent
65bae2f18c
commit
a24da791b8
@ -80,6 +80,9 @@ typedef virResctrlInfoPerType *virResctrlInfoPerTypePtr;
|
|||||||
typedef struct _virResctrlInfoPerLevel virResctrlInfoPerLevel;
|
typedef struct _virResctrlInfoPerLevel virResctrlInfoPerLevel;
|
||||||
typedef virResctrlInfoPerLevel *virResctrlInfoPerLevelPtr;
|
typedef virResctrlInfoPerLevel *virResctrlInfoPerLevelPtr;
|
||||||
|
|
||||||
|
typedef struct _virResctrlInfoMemBW virResctrlInfoMemBW;
|
||||||
|
typedef virResctrlInfoMemBW *virResctrlInfoMemBWPtr;
|
||||||
|
|
||||||
typedef struct _virResctrlAllocPerType virResctrlAllocPerType;
|
typedef struct _virResctrlAllocPerType virResctrlAllocPerType;
|
||||||
typedef virResctrlAllocPerType *virResctrlAllocPerTypePtr;
|
typedef virResctrlAllocPerType *virResctrlAllocPerTypePtr;
|
||||||
|
|
||||||
@ -116,11 +119,30 @@ struct _virResctrlInfoPerLevel {
|
|||||||
virResctrlInfoPerTypePtr *types;
|
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 {
|
struct _virResctrlInfo {
|
||||||
virObject parent;
|
virObject parent;
|
||||||
|
|
||||||
virResctrlInfoPerLevelPtr *levels;
|
virResctrlInfoPerLevelPtr *levels;
|
||||||
size_t nlevels;
|
size_t nlevels;
|
||||||
|
|
||||||
|
virResctrlInfoMemBWPtr membw_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -146,6 +168,7 @@ virResctrlInfoDispose(void *obj)
|
|||||||
VIR_FREE(level);
|
VIR_FREE(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VIR_FREE(resctrl->membw_info);
|
||||||
VIR_FREE(resctrl->levels);
|
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
|
static int
|
||||||
virResctrlGetInfo(virResctrlInfoPtr resctrl)
|
virResctrlGetInfo(virResctrlInfoPtr resctrl)
|
||||||
{
|
{
|
||||||
@ -452,6 +529,10 @@ virResctrlGetInfo(virResctrlInfoPtr resctrl)
|
|||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = virResctrlGetMemoryBandwidthInfo(resctrl);
|
||||||
|
if (ret < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
ret = virResctrlGetCacheInfo(resctrl, dirp);
|
ret = virResctrlGetCacheInfo(resctrl, dirp);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -493,6 +574,9 @@ virResctrlInfoIsEmpty(virResctrlInfoPtr resctrl)
|
|||||||
if (!resctrl)
|
if (!resctrl)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (resctrl->membw_info)
|
||||||
|
return false;
|
||||||
|
|
||||||
for (i = 0; i < resctrl->nlevels; i++) {
|
for (i = 0; i < resctrl->nlevels; i++) {
|
||||||
virResctrlInfoPerLevelPtr i_level = resctrl->levels[i];
|
virResctrlInfoPerLevelPtr i_level = resctrl->levels[i];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user