Blame SOURCES/libvirt-util-Use-default-group-s-mask-for-unspecified-resctrl-allocations.patch

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