|
|
99cbc7 |
From c402803b725543f690abd96175df12dbee224c58 Mon Sep 17 00:00:00 2001
|
|
|
99cbc7 |
Message-Id: <c402803b725543f690abd96175df12dbee224c58@dist-git>
|
|
|
99cbc7 |
From: Bing Niu <bing.niu@intel.com>
|
|
|
99cbc7 |
Date: Mon, 15 Apr 2019 17:32:47 +0200
|
|
|
99cbc7 |
Subject: [PATCH] util: Add MBA capability information query to resctrl
|
|
|
99cbc7 |
MIME-Version: 1.0
|
|
|
99cbc7 |
Content-Type: text/plain; charset=UTF-8
|
|
|
99cbc7 |
Content-Transfer-Encoding: 8bit
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Introducing virResctrlInfoMemBW for the information memory bandwidth
|
|
|
99cbc7 |
allocation information.
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Signed-off-by: Bing Niu <bing.niu@intel.com>
|
|
|
99cbc7 |
Reviewed-by: John Ferlan <jferlan@redhat.com>
|
|
|
99cbc7 |
(cherry picked from commit a24da791b8d489600807158c45451012ae1a8270)
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
|
|
|
99cbc7 |
Message-Id: <5bf94bb7ee189420dfd99b19ff423c9650b1e637.1555342313.git.phrdina@redhat.com>
|
|
|
99cbc7 |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
99cbc7 |
---
|
|
|
99cbc7 |
src/util/virresctrl.c | 84 +++++++++++++++++++++++++++++++++++++++++++
|
|
|
99cbc7 |
1 file changed, 84 insertions(+)
|
|
|
99cbc7 |
|
|
|
99cbc7 |
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
|
|
|
99cbc7 |
index a38c9261b6..b12a05cb0f 100644
|
|
|
99cbc7 |
--- a/src/util/virresctrl.c
|
|
|
99cbc7 |
+++ b/src/util/virresctrl.c
|
|
|
99cbc7 |
@@ -80,6 +80,9 @@ typedef virResctrlInfoPerType *virResctrlInfoPerTypePtr;
|
|
|
99cbc7 |
typedef struct _virResctrlInfoPerLevel virResctrlInfoPerLevel;
|
|
|
99cbc7 |
typedef virResctrlInfoPerLevel *virResctrlInfoPerLevelPtr;
|
|
|
99cbc7 |
|
|
|
99cbc7 |
+typedef struct _virResctrlInfoMemBW virResctrlInfoMemBW;
|
|
|
99cbc7 |
+typedef virResctrlInfoMemBW *virResctrlInfoMemBWPtr;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
typedef struct _virResctrlAllocPerType virResctrlAllocPerType;
|
|
|
99cbc7 |
typedef virResctrlAllocPerType *virResctrlAllocPerTypePtr;
|
|
|
99cbc7 |
|
|
|
99cbc7 |
@@ -116,11 +119,30 @@ struct _virResctrlInfoPerLevel {
|
|
|
99cbc7 |
virResctrlInfoPerTypePtr *types;
|
|
|
99cbc7 |
};
|
|
|
99cbc7 |
|
|
|
99cbc7 |
+/* Information about memory bandwidth allocation */
|
|
|
99cbc7 |
+struct _virResctrlInfoMemBW {
|
|
|
99cbc7 |
+ /* minimum memory bandwidth allowed */
|
|
|
99cbc7 |
+ unsigned int min_bandwidth;
|
|
|
99cbc7 |
+ /* bandwidth granularity */
|
|
|
99cbc7 |
+ unsigned int bandwidth_granularity;
|
|
|
99cbc7 |
+ /* Maximum number of simultaneous allocations */
|
|
|
99cbc7 |
+ unsigned int max_allocation;
|
|
|
99cbc7 |
+ /* level number of last level cache */
|
|
|
99cbc7 |
+ unsigned int last_level_cache;
|
|
|
99cbc7 |
+ /* max id of last level cache, this is used to track
|
|
|
99cbc7 |
+ * how many last level cache available in host system,
|
|
|
99cbc7 |
+ * the number of memory bandwidth allocation controller
|
|
|
99cbc7 |
+ * is identical with last level cache. */
|
|
|
99cbc7 |
+ unsigned int max_id;
|
|
|
99cbc7 |
+};
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
struct _virResctrlInfo {
|
|
|
99cbc7 |
virObject parent;
|
|
|
99cbc7 |
|
|
|
99cbc7 |
virResctrlInfoPerLevelPtr *levels;
|
|
|
99cbc7 |
size_t nlevels;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ virResctrlInfoMemBWPtr membw_info;
|
|
|
99cbc7 |
};
|
|
|
99cbc7 |
|
|
|
99cbc7 |
|
|
|
99cbc7 |
@@ -146,6 +168,7 @@ virResctrlInfoDispose(void *obj)
|
|
|
99cbc7 |
VIR_FREE(level);
|
|
|
99cbc7 |
}
|
|
|
99cbc7 |
|
|
|
99cbc7 |
+ VIR_FREE(resctrl->membw_info);
|
|
|
99cbc7 |
VIR_FREE(resctrl->levels);
|
|
|
99cbc7 |
}
|
|
|
99cbc7 |
|
|
|
99cbc7 |
@@ -442,6 +465,60 @@ virResctrlGetCacheInfo(virResctrlInfoPtr resctrl,
|
|
|
99cbc7 |
}
|
|
|
99cbc7 |
|
|
|
99cbc7 |
|
|
|
99cbc7 |
+static int
|
|
|
99cbc7 |
+virResctrlGetMemoryBandwidthInfo(virResctrlInfoPtr resctrl)
|
|
|
99cbc7 |
+{
|
|
|
99cbc7 |
+ int ret = -1;
|
|
|
99cbc7 |
+ int rv = -1;
|
|
|
99cbc7 |
+ virResctrlInfoMemBWPtr i_membw = NULL;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ /* query memory bandwidth allocation info */
|
|
|
99cbc7 |
+ if (VIR_ALLOC(i_membw) < 0)
|
|
|
99cbc7 |
+ goto cleanup;
|
|
|
99cbc7 |
+ rv = virFileReadValueUint(&i_membw->bandwidth_granularity,
|
|
|
99cbc7 |
+ SYSFS_RESCTRL_PATH "/info/MB/bandwidth_gran");
|
|
|
99cbc7 |
+ if (rv == -2) {
|
|
|
99cbc7 |
+ /* The file doesn't exist, so it's unusable for us,
|
|
|
99cbc7 |
+ * probably memory bandwidth allocation unsupported */
|
|
|
99cbc7 |
+ VIR_INFO("The path '" SYSFS_RESCTRL_PATH "/info/MB/bandwidth_gran'"
|
|
|
99cbc7 |
+ "does not exist");
|
|
|
99cbc7 |
+ ret = 0;
|
|
|
99cbc7 |
+ goto cleanup;
|
|
|
99cbc7 |
+ } else if (rv < 0) {
|
|
|
99cbc7 |
+ /* Other failures are fatal, so just quit */
|
|
|
99cbc7 |
+ goto cleanup;
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ rv = virFileReadValueUint(&i_membw->min_bandwidth,
|
|
|
99cbc7 |
+ SYSFS_RESCTRL_PATH "/info/MB/min_bandwidth");
|
|
|
99cbc7 |
+ if (rv == -2) {
|
|
|
99cbc7 |
+ /* If the previous file exists, so should this one. Hence -2 is
|
|
|
99cbc7 |
+ * fatal in this case (errors out in next condition) - the kernel
|
|
|
99cbc7 |
+ * interface might've changed too much or something else is wrong. */
|
|
|
99cbc7 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
99cbc7 |
+ _("Cannot get min bandwidth from resctrl memory info"));
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+ if (rv < 0)
|
|
|
99cbc7 |
+ goto cleanup;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ rv = virFileReadValueUint(&i_membw->max_allocation,
|
|
|
99cbc7 |
+ SYSFS_RESCTRL_PATH "/info/MB/num_closids");
|
|
|
99cbc7 |
+ if (rv == -2) {
|
|
|
99cbc7 |
+ /* Similar reasoning to min_bandwidth above. */
|
|
|
99cbc7 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
99cbc7 |
+ _("Cannot get max allocation from resctrl memory info"));
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+ if (rv < 0)
|
|
|
99cbc7 |
+ goto cleanup;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ VIR_STEAL_PTR(resctrl->membw_info, i_membw);
|
|
|
99cbc7 |
+ ret = 0;
|
|
|
99cbc7 |
+ cleanup:
|
|
|
99cbc7 |
+ VIR_FREE(i_membw);
|
|
|
99cbc7 |
+ return ret;
|
|
|
99cbc7 |
+}
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
static int
|
|
|
99cbc7 |
virResctrlGetInfo(virResctrlInfoPtr resctrl)
|
|
|
99cbc7 |
{
|
|
|
99cbc7 |
@@ -452,6 +529,10 @@ virResctrlGetInfo(virResctrlInfoPtr resctrl)
|
|
|
99cbc7 |
if (ret <= 0)
|
|
|
99cbc7 |
goto cleanup;
|
|
|
99cbc7 |
|
|
|
99cbc7 |
+ ret = virResctrlGetMemoryBandwidthInfo(resctrl);
|
|
|
99cbc7 |
+ if (ret < 0)
|
|
|
99cbc7 |
+ goto cleanup;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
ret = virResctrlGetCacheInfo(resctrl, dirp);
|
|
|
99cbc7 |
if (ret < 0)
|
|
|
99cbc7 |
goto cleanup;
|
|
|
99cbc7 |
@@ -493,6 +574,9 @@ virResctrlInfoIsEmpty(virResctrlInfoPtr resctrl)
|
|
|
99cbc7 |
if (!resctrl)
|
|
|
99cbc7 |
return true;
|
|
|
99cbc7 |
|
|
|
99cbc7 |
+ if (resctrl->membw_info)
|
|
|
99cbc7 |
+ return false;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
for (i = 0; i < resctrl->nlevels; i++) {
|
|
|
99cbc7 |
virResctrlInfoPerLevelPtr i_level = resctrl->levels[i];
|
|
|
99cbc7 |
|
|
|
99cbc7 |
--
|
|
|
99cbc7 |
2.21.0
|
|
|
99cbc7 |
|