|
|
c1c534 |
From 4574632d3d8eb9be947f0dd052a5d5a72fc306b7 Mon Sep 17 00:00:00 2001
|
|
|
c1c534 |
Message-Id: <4574632d3d8eb9be947f0dd052a5d5a72fc306b7@dist-git>
|
|
|
c1c534 |
From: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c1c534 |
Date: Wed, 31 Jan 2018 16:32:41 +0100
|
|
|
c1c534 |
Subject: [PATCH] util: Use default group's mask for unspecified resctrl
|
|
|
c1c534 |
allocations
|
|
|
c1c534 |
|
|
|
c1c534 |
Introduce virResctrlAllocCopyMasks() and use that to initially copy the default
|
|
|
c1c534 |
group schemata to the allocation before reserving any parts of the cache. The
|
|
|
c1c534 |
reason for this is that when new group is created the schemata will have unknown
|
|
|
c1c534 |
data in it. If there was previously group with the same CLoS ID, it will have
|
|
|
c1c534 |
the previous valies, if not it will have all bits set. And we need to set all
|
|
|
c1c534 |
unspecified (in the XML) allocations to the same one as the default group.
|
|
|
c1c534 |
|
|
|
c1c534 |
Some non-Linux functions now need to be made public due to this change.
|
|
|
c1c534 |
|
|
|
c1c534 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1289368
|
|
|
c1c534 |
|
|
|
c1c534 |
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c1c534 |
(cherry picked from commit c39ce914dd88c35a66d1088f0688da24fea8cfcd)
|
|
|
c1c534 |
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c1c534 |
---
|
|
|
c1c534 |
src/util/virresctrl.c | 72 +++++++++++++++++++++++++++++++++++----------------
|
|
|
c1c534 |
1 file changed, 50 insertions(+), 22 deletions(-)
|
|
|
c1c534 |
|
|
|
c1c534 |
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
|
|
|
c1c534 |
index df6461a046..a0ea274871 100644
|
|
|
c1c534 |
--- a/src/util/virresctrl.c
|
|
|
c1c534 |
+++ b/src/util/virresctrl.c
|
|
|
c1c534 |
@@ -667,8 +667,6 @@ virResctrlAllocGetType(virResctrlAllocPtr resctrl,
|
|
|
c1c534 |
}
|
|
|
c1c534 |
|
|
|
c1c534 |
|
|
|
c1c534 |
-#ifdef __linux__
|
|
|
c1c534 |
-
|
|
|
c1c534 |
static int
|
|
|
c1c534 |
virResctrlAllocUpdateMask(virResctrlAllocPtr resctrl,
|
|
|
c1c534 |
unsigned int level,
|
|
|
c1c534 |
@@ -696,8 +694,6 @@ virResctrlAllocUpdateMask(virResctrlAllocPtr resctrl,
|
|
|
c1c534 |
return virBitmapCopy(a_type->masks[cache], mask);
|
|
|
c1c534 |
}
|
|
|
c1c534 |
|
|
|
c1c534 |
-#endif
|
|
|
c1c534 |
-
|
|
|
c1c534 |
|
|
|
c1c534 |
static int
|
|
|
c1c534 |
virResctrlAllocUpdateSize(virResctrlAllocPtr resctrl,
|
|
|
c1c534 |
@@ -917,8 +913,6 @@ virResctrlAllocFormat(virResctrlAllocPtr resctrl)
|
|
|
c1c534 |
}
|
|
|
c1c534 |
|
|
|
c1c534 |
|
|
|
c1c534 |
-#ifdef __linux__
|
|
|
c1c534 |
-
|
|
|
c1c534 |
static int
|
|
|
c1c534 |
virResctrlAllocParseProcessCache(virResctrlInfoPtr resctrl,
|
|
|
c1c534 |
virResctrlAllocPtr alloc,
|
|
|
c1c534 |
@@ -1090,6 +1084,8 @@ virResctrlAllocGetDefault(virResctrlInfoPtr resctrl)
|
|
|
c1c534 |
}
|
|
|
c1c534 |
|
|
|
c1c534 |
|
|
|
c1c534 |
+#ifdef __linux__
|
|
|
c1c534 |
+
|
|
|
c1c534 |
static void
|
|
|
c1c534 |
virResctrlAllocSubtractPerType(virResctrlAllocPerTypePtr dst,
|
|
|
c1c534 |
virResctrlAllocPerTypePtr src)
|
|
|
c1c534 |
@@ -1298,23 +1294,8 @@ virResctrlAllocFindUnused(virResctrlAllocPerTypePtr a_type,
|
|
|
c1c534 |
ssize_t last_bits = 0;
|
|
|
c1c534 |
ssize_t last_pos = -1;
|
|
|
c1c534 |
|
|
|
c1c534 |
- /* If there is no reservation requested we need to set all bits. That's due
|
|
|
c1c534 |
- * to weird interface of the resctrl sysfs. It's also the reason why we
|
|
|
c1c534 |
- * cannot reserve the whole cache in one allocation. */
|
|
|
c1c534 |
- if (!size) {
|
|
|
c1c534 |
- a_mask = virBitmapNew(i_type->bits);
|
|
|
c1c534 |
- if (!a_mask)
|
|
|
c1c534 |
- return -1;
|
|
|
c1c534 |
-
|
|
|
c1c534 |
- virBitmapSetAll(a_mask);
|
|
|
c1c534 |
-
|
|
|
c1c534 |
- if (virResctrlAllocSetMask(a_type, cache, a_mask) < 0) {
|
|
|
c1c534 |
- virBitmapFree(a_mask);
|
|
|
c1c534 |
- return -1;
|
|
|
c1c534 |
- }
|
|
|
c1c534 |
-
|
|
|
c1c534 |
+ if (!size)
|
|
|
c1c534 |
return 0;
|
|
|
c1c534 |
- }
|
|
|
c1c534 |
|
|
|
c1c534 |
if (cache >= f_type->nmasks) {
|
|
|
c1c534 |
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
c1c534 |
@@ -1417,6 +1398,44 @@ virResctrlAllocFindUnused(virResctrlAllocPerTypePtr a_type,
|
|
|
c1c534 |
}
|
|
|
c1c534 |
|
|
|
c1c534 |
|
|
|
c1c534 |
+static int
|
|
|
c1c534 |
+virResctrlAllocCopyMasks(virResctrlAllocPtr dst,
|
|
|
c1c534 |
+ virResctrlAllocPtr src)
|
|
|
c1c534 |
+{
|
|
|
c1c534 |
+ unsigned int level = 0;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ for (level = 0; level < src->nlevels; level++) {
|
|
|
c1c534 |
+ virResctrlAllocPerLevelPtr s_level = src->levels[level];
|
|
|
c1c534 |
+ unsigned int type = 0;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (!s_level)
|
|
|
c1c534 |
+ continue;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ for (type = 0; type < VIR_CACHE_TYPE_LAST; type++) {
|
|
|
c1c534 |
+ virResctrlAllocPerTypePtr s_type = s_level->types[type];
|
|
|
c1c534 |
+ virResctrlAllocPerTypePtr d_type = NULL;
|
|
|
c1c534 |
+ unsigned int cache = 0;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (!s_type)
|
|
|
c1c534 |
+ continue;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ d_type = virResctrlAllocGetType(dst, level, type);
|
|
|
c1c534 |
+ if (!d_type)
|
|
|
c1c534 |
+ return -1;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ for (cache = 0; cache < s_type->nmasks; cache++) {
|
|
|
c1c534 |
+ virBitmapPtr mask = s_type->masks[cache];
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (mask && virResctrlAllocUpdateMask(dst, level, type, cache, mask) < 0)
|
|
|
c1c534 |
+ return -1;
|
|
|
c1c534 |
+ }
|
|
|
c1c534 |
+ }
|
|
|
c1c534 |
+ }
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ return 0;
|
|
|
c1c534 |
+}
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+
|
|
|
c1c534 |
/*
|
|
|
c1c534 |
* This function is called when creating an allocation in the system. What it
|
|
|
c1c534 |
* does is that it gets all the unused bits using virResctrlAllocGetUnused() and
|
|
|
c1c534 |
@@ -1430,11 +1449,19 @@ virResctrlAllocMasksAssign(virResctrlInfoPtr resctrl,
|
|
|
c1c534 |
int ret = -1;
|
|
|
c1c534 |
unsigned int level = 0;
|
|
|
c1c534 |
virResctrlAllocPtr alloc_free = NULL;
|
|
|
c1c534 |
+ virResctrlAllocPtr alloc_default = NULL;
|
|
|
c1c534 |
|
|
|
c1c534 |
alloc_free = virResctrlAllocGetUnused(resctrl);
|
|
|
c1c534 |
if (!alloc_free)
|
|
|
c1c534 |
return -1;
|
|
|
c1c534 |
|
|
|
c1c534 |
+ alloc_default = virResctrlAllocGetDefault(resctrl);
|
|
|
c1c534 |
+ if (!alloc_default)
|
|
|
c1c534 |
+ return -1;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (virResctrlAllocCopyMasks(alloc, alloc_default) < 0)
|
|
|
c1c534 |
+ return -1;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
for (level = 0; level < alloc->nlevels; level++) {
|
|
|
c1c534 |
virResctrlAllocPerLevelPtr a_level = alloc->levels[level];
|
|
|
c1c534 |
virResctrlAllocPerLevelPtr f_level = NULL;
|
|
|
c1c534 |
@@ -1482,6 +1509,7 @@ virResctrlAllocMasksAssign(virResctrlInfoPtr resctrl,
|
|
|
c1c534 |
ret = 0;
|
|
|
c1c534 |
cleanup:
|
|
|
c1c534 |
virObjectUnref(alloc_free);
|
|
|
c1c534 |
+ virObjectUnref(alloc_default);
|
|
|
c1c534 |
return ret;
|
|
|
c1c534 |
}
|
|
|
c1c534 |
|
|
|
c1c534 |
--
|
|
|
c1c534 |
2.16.1
|
|
|
c1c534 |
|