[PATCH 09/10] resctrl: Do not use max_id for

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Martin Kletzander <mkletzan@xxxxxxxxxx>
---
 src/conf/capabilities.c |  5 ++-
 src/util/virresctrl.c   | 77 ++++++++++++++++++++++++-----------------
 src/util/virresctrl.h   |  3 ++
 3 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index 1d3b7050b2e3..3d0602e1b6fe 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -2128,7 +2128,9 @@ virCapabilitiesInitResctrlMemory(virCaps *caps)
         node = g_new0(virCapsHostMemBWNode, 1);
 
         if (virResctrlInfoGetMemoryBandwidth(caps->host.resctrl,
-                                             bank->level, &node->control) > 0) {
+                                             bank->level,
+                                             bank->id,
+                                             &node->control) > 0) {
             node->id = bank->id;
             node->cpus = virBitmapNewCopy(bank->cpus);
 
@@ -2269,6 +2271,7 @@ virCapabilitiesInitCaches(virCaps *caps)
             if (i == caps->host.cache.nbanks) {
                 /* If it is a new cache, then update its resctrl information. */
                 if (virResctrlInfoGetCache(caps->host.resctrl,
+                                           bank->id,
                                            bank->level,
                                            bank->size,
                                            &bank->ncontrols,
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index f3ec4d67059f..3acc1447ad56 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -121,6 +121,7 @@ struct _virResctrlInfoPerType {
     unsigned int bits;
     unsigned int max_cache_id;
 
+    virBitmap *cache_ids;
     /* In order to be self-sufficient we need size information per cache.
      * Funnily enough, one of the outcomes of the resctrl design is that it
      * does not account for different sizes per cache on the same level.  So
@@ -146,11 +147,8 @@ struct _virResctrlInfoMemBW {
     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;
+
+    virBitmap *cache_ids;
 };
 
 struct _virResctrlInfoMongrp {
@@ -192,6 +190,7 @@ virResctrlInfoMemBWFree(virResctrlInfoMemBW *ptr)
     if (!ptr)
         return;
 
+    virBitmapFree(ptr->cache_ids);
     g_free(ptr);
 }
 
@@ -203,6 +202,7 @@ virResctrlInfoPerTypeFree(virResctrlInfoPerType *ptr)
     if (!ptr)
         return;
 
+    virBitmapFree(ptr->cache_ids);
     g_free(ptr);
 }
 
@@ -848,6 +848,7 @@ virResctrlInfoIsEmpty(virResctrlInfo *resctrl)
 int
 virResctrlInfoGetMemoryBandwidth(virResctrlInfo *resctrl,
                                  unsigned int level,
+                                 unsigned int id,
                                  virResctrlInfoMemBWPerNode *control)
 {
     virResctrlInfoMemBW *membw_info = resctrl->membw_info;
@@ -858,6 +859,13 @@ virResctrlInfoGetMemoryBandwidth(virResctrlInfo *resctrl,
     if (membw_info->last_level_cache != level)
         return 0;
 
+    /* This "should not happen", but resctrl code is constantly full of
+     * surprises.  Warning might make us aware in the future. */
+    if (!virBitmapIsBitSet(membw_info->cache_ids, id)) {
+        VIR_WARN("Memory bandwidth for cache id %u is not recorded in list of cache IDs",
+                 id);
+    }
+
     control->granularity = membw_info->bandwidth_granularity;
     control->min = membw_info->min_bandwidth;
     control->max_allocation = membw_info->max_allocation;
@@ -867,6 +875,7 @@ virResctrlInfoGetMemoryBandwidth(virResctrlInfo *resctrl,
 
 int
 virResctrlInfoGetCache(virResctrlInfo *resctrl,
+                       unsigned int id,
                        unsigned int level,
                        unsigned long long size,
                        size_t *ncontrols,
@@ -885,12 +894,15 @@ virResctrlInfoGetCache(virResctrlInfo *resctrl,
     if (resctrl->membw_info) {
         virResctrlInfoMemBW *membw_info = resctrl->membw_info;
 
+        if (!membw_info->cache_ids)
+            membw_info->cache_ids = virBitmapNew(0);
+
         if (level > membw_info->last_level_cache) {
             membw_info->last_level_cache = level;
-            membw_info->max_id = 0;
-        } else if (membw_info->last_level_cache == level) {
-            membw_info->max_id++;
+            virBitmapShrink(membw_info->cache_ids, 0);
         }
+
+        virBitmapSetBitExpand(membw_info->cache_ids, id);
     }
 
     if (level >= resctrl->nlevels)
@@ -905,6 +917,11 @@ virResctrlInfoGetCache(virResctrlInfo *resctrl,
         if (!i_type)
             continue;
 
+        if (!i_type->cache_ids)
+            i_type->cache_ids = virBitmapNew(id);
+
+        virBitmapSetBitExpand(i_type->cache_ids, id);
+
         /* Let's take the opportunity to update our internal information about
          * the cache size */
         if (!i_type->size) {
@@ -919,7 +936,6 @@ virResctrlInfoGetCache(virResctrlInfo *resctrl,
                                level, i_type->size, size);
                 goto error;
             }
-            i_type->max_cache_id++;
         }
 
         VIR_EXPAND_N(*controls, *ncontrols, 1);
@@ -1418,8 +1434,7 @@ virResctrlAllocMemoryBandwidthFormat(virResctrlAlloc *alloc,
 
 
 static int
-virResctrlAllocParseProcessMemoryBandwidth(virResctrlInfo *resctrl,
-                                           virResctrlAlloc *alloc,
+virResctrlAllocParseProcessMemoryBandwidth(virResctrlAlloc *alloc,
                                            char *mem_bw)
 {
     unsigned int bandwidth;
@@ -1442,12 +1457,6 @@ virResctrlAllocParseProcessMemoryBandwidth(virResctrlInfo *resctrl,
                        _("Invalid bandwidth %1$u"), bandwidth);
         return -1;
     }
-    if (id > resctrl->membw_info->max_id) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Missing or inconsistent resctrl info for memory bandwidth node '%1$u'"),
-                       id);
-        return -1;
-    }
     if (alloc->mem_bw->nbandwidths <= id) {
         VIR_EXPAND_N(alloc->mem_bw->bandwidths, alloc->mem_bw->nbandwidths,
                      id - alloc->mem_bw->nbandwidths + 1);
@@ -1495,7 +1504,7 @@ virResctrlAllocParseMemoryBandwidthLine(virResctrlInfo *resctrl,
 
     mbs = g_strsplit(tmp, ";", 0);
     for (next = mbs; *next; next++) {
-        if (virResctrlAllocParseProcessMemoryBandwidth(resctrl, alloc, *next) < 0)
+        if (virResctrlAllocParseProcessMemoryBandwidth(alloc, *next) < 0)
             return -1;
     }
 
@@ -1597,7 +1606,8 @@ virResctrlAllocParseProcessCache(virResctrlInfo *resctrl,
     if (!resctrl ||
         level >= resctrl->nlevels ||
         !resctrl->levels[level] ||
-        !resctrl->levels[level]->types[type]) {
+        !resctrl->levels[level]->types[type] ||
+        !virBitmapIsBitSet(resctrl->levels[level]->types[type]->cache_ids, cache_id)) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Missing or inconsistent resctrl info for level '%1$u' type '%2$s'"),
                        level, virCacheTypeToString(type));
@@ -1790,7 +1800,7 @@ virResctrlAllocNewFromInfo(virResctrlInfo *info)
         for (j = 0; j < VIR_CACHE_TYPE_LAST; j++) {
             virResctrlInfoPerType *i_type = i_level->types[j];
             g_autoptr(virBitmap) mask = NULL;
-            size_t k = 0;
+            ssize_t bit = -1;
 
             if (!i_type)
                 continue;
@@ -1798,8 +1808,8 @@ virResctrlAllocNewFromInfo(virResctrlInfo *info)
             mask = virBitmapNew(i_type->bits);
             virBitmapSetAll(mask);
 
-            for (k = 0; k <= i_type->max_cache_id; k++) {
-                if (virResctrlAllocUpdateMask(ret, i, j, k, mask) < 0)
+            while ((bit = virBitmapNextSetBit(i_type->cache_ids, bit)) >= 0) {
+                if (virResctrlAllocUpdateMask(ret, i, j, bit, mask) < 0)
                     return NULL;
             }
         }
@@ -1830,10 +1840,21 @@ virResctrlAllocCopyMemBW(virResctrlAlloc *dst,
                      src_bw->nbandwidths - dst_bw->nbandwidths);
 
     for (i = 0; i < src_bw->nbandwidths; i++) {
-        if (dst_bw->bandwidths[i])
+        if (!src_bw->bandwidths[i]) {
+            if (!dst_bw->bandwidths[i])
+                continue;
+
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("bandwidth controller id %1$zd does not exist"),
+                           i);
+            return -1;
+        }
+
+        if (!dst_bw->bandwidths[i]) {
+            dst_bw->bandwidths[i] = g_new0(unsigned int, 1);
+            *dst_bw->bandwidths[i] = *src_bw->bandwidths[i];
             continue;
-        dst_bw->bandwidths[i] = g_new0(unsigned int, 1);
-        *dst_bw->bandwidths[i] = *src_bw->bandwidths[i];
+        }
     }
 
     return 0;
@@ -2065,12 +2086,6 @@ virResctrlAllocMemoryBandwidth(virResctrlInfo *resctrl,
                            mem_bw_info->min_bandwidth);
             return -1;
         }
-        if (i > mem_bw_info->max_id) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("bandwidth controller id %1$zd does not exist, max controller id %2$u"),
-                           i, mem_bw_info->max_id);
-            return -1;
-        }
     }
     return 0;
 }
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index 0e4b535f9e52..c70b112864eb 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -47,6 +47,7 @@ VIR_ENUM_DECL(virResctrlMonitorPrefix);
 
 typedef struct _virResctrlInfoPerCache virResctrlInfoPerCache;
 struct _virResctrlInfoPerCache {
+    unsigned int id;
     /* Smallest possible increase of the allocation size in bytes */
     unsigned long long granularity;
     /* Minimal allocatable size in bytes (if different from granularity) */
@@ -96,6 +97,7 @@ virResctrlInfoNew(void);
 
 int
 virResctrlInfoGetCache(virResctrlInfo *resctrl,
+                       unsigned int id,
                        unsigned int level,
                        unsigned long long size,
                        size_t *ncontrols,
@@ -104,6 +106,7 @@ virResctrlInfoGetCache(virResctrlInfo *resctrl,
 int
 virResctrlInfoGetMemoryBandwidth(virResctrlInfo *resctrl,
                                  unsigned int level,
+                                 unsigned int id,
                                  virResctrlInfoMemBWPerNode *control);
 /* Alloc-related things */
 typedef struct _virResctrlAlloc virResctrlAlloc;
-- 
2.46.0




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux