|
|
c1c534 |
From fbecdf5ed4345a15d1ffc30922d44272a3d60368 Mon Sep 17 00:00:00 2001
|
|
|
c1c534 |
Message-Id: <fbecdf5ed4345a15d1ffc30922d44272a3d60368@dist-git>
|
|
|
c1c534 |
From: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c1c534 |
Date: Fri, 2 Feb 2018 15:21:27 +0100
|
|
|
c1c534 |
Subject: [PATCH] util: Clear unused part of the map in virBitmapShrink
|
|
|
c1c534 |
|
|
|
c1c534 |
Some of the other functions depend on the fact that unused bits and longs are
|
|
|
c1c534 |
always zero and it's less error-prone to clear it than fix the other functions.
|
|
|
c1c534 |
It's enough to zero out one piece of the map since we're calling realloc() to
|
|
|
c1c534 |
get rid of the rest (and updating map_len).
|
|
|
c1c534 |
|
|
|
c1c534 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1540817
|
|
|
c1c534 |
|
|
|
c1c534 |
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c1c534 |
(cherry picked from commit d6e582da80d07a90f154dc27aca239d44fc2b7b7)
|
|
|
c1c534 |
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c1c534 |
---
|
|
|
c1c534 |
src/conf/domain_conf.c | 4 +++-
|
|
|
c1c534 |
src/util/virbitmap.c | 30 ++++++++++++++++++++++--------
|
|
|
c1c534 |
src/util/virbitmap.h | 2 +-
|
|
|
c1c534 |
src/util/virresctrl.c | 3 ++-
|
|
|
c1c534 |
tests/virbitmaptest.c | 8 ++++++++
|
|
|
c1c534 |
5 files changed, 36 insertions(+), 11 deletions(-)
|
|
|
c1c534 |
|
|
|
c1c534 |
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
|
c1c534 |
index 181b035647..0af3dd5ab6 100644
|
|
|
c1c534 |
--- a/src/conf/domain_conf.c
|
|
|
c1c534 |
+++ b/src/conf/domain_conf.c
|
|
|
c1c534 |
@@ -18365,7 +18365,9 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
|
|
|
c1c534 |
|
|
|
c1c534 |
/* We need to limit the bitmap to number of vCPUs. If there's nothing left,
|
|
|
c1c534 |
* then we can just clean up and return 0 immediately */
|
|
|
c1c534 |
- virBitmapShrink(vcpus, def->maxvcpus);
|
|
|
c1c534 |
+ if (virBitmapShrink(vcpus, def->maxvcpus) < 0)
|
|
|
c1c534 |
+ goto cleanup;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
if (virBitmapIsAllClear(vcpus)) {
|
|
|
c1c534 |
ret = 0;
|
|
|
c1c534 |
goto cleanup;
|
|
|
c1c534 |
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
|
|
|
c1c534 |
index b2c5c7a6a5..33cae2f305 100644
|
|
|
c1c534 |
--- a/src/util/virbitmap.c
|
|
|
c1c534 |
+++ b/src/util/virbitmap.c
|
|
|
c1c534 |
@@ -1201,21 +1201,35 @@ virBitmapSubtract(virBitmapPtr a,
|
|
|
c1c534 |
/**
|
|
|
c1c534 |
* virBitmapShrink:
|
|
|
c1c534 |
* @map: Pointer to bitmap
|
|
|
c1c534 |
- * @b: last bit position to be excluded from bitmap
|
|
|
c1c534 |
+ * @b: Size to reduce the bitmap to
|
|
|
c1c534 |
*
|
|
|
c1c534 |
- * Resizes the bitmap so that no more than @b bits will fit into it. Nothing
|
|
|
c1c534 |
- * will change if the size is already smaller than @b.
|
|
|
c1c534 |
- *
|
|
|
c1c534 |
- * NB: Does not adjust the map->map_len so that a subsequent virBitmapExpand
|
|
|
c1c534 |
- * doesn't necessarily need to reallocate.
|
|
|
c1c534 |
+ * Reduces the bitmap to size @b. Nothing will change if the size is already
|
|
|
c1c534 |
+ * smaller than or equal to @b.
|
|
|
c1c534 |
*/
|
|
|
c1c534 |
-void
|
|
|
c1c534 |
+int
|
|
|
c1c534 |
virBitmapShrink(virBitmapPtr map,
|
|
|
c1c534 |
size_t b)
|
|
|
c1c534 |
{
|
|
|
c1c534 |
+ size_t nl = 0;
|
|
|
c1c534 |
+ size_t nb = 0;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
if (!map)
|
|
|
c1c534 |
- return;
|
|
|
c1c534 |
+ return 0;
|
|
|
c1c534 |
|
|
|
c1c534 |
if (map->max_bit >= b)
|
|
|
c1c534 |
map->max_bit = b;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ nl = map->max_bit / VIR_BITMAP_BITS_PER_UNIT;
|
|
|
c1c534 |
+ nb = map->max_bit % VIR_BITMAP_BITS_PER_UNIT;
|
|
|
c1c534 |
+ map->map[nl] &= ((1UL << nb) - 1);
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ nl++;
|
|
|
c1c534 |
+ if (nl == map->map_len)
|
|
|
c1c534 |
+ return 0;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (VIR_REALLOC_N(map->map, nl) < 0)
|
|
|
c1c534 |
+ return -1;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ map->map_len = nl;
|
|
|
c1c534 |
+ return 0;
|
|
|
c1c534 |
}
|
|
|
c1c534 |
diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h
|
|
|
c1c534 |
index 2464814055..5a3362a19f 100644
|
|
|
c1c534 |
--- a/src/util/virbitmap.h
|
|
|
c1c534 |
+++ b/src/util/virbitmap.h
|
|
|
c1c534 |
@@ -153,6 +153,6 @@ void virBitmapIntersect(virBitmapPtr a, virBitmapPtr b)
|
|
|
c1c534 |
void virBitmapSubtract(virBitmapPtr a, virBitmapPtr b)
|
|
|
c1c534 |
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
|
c1c534 |
|
|
|
c1c534 |
-void virBitmapShrink(virBitmapPtr map, size_t b);
|
|
|
c1c534 |
+int virBitmapShrink(virBitmapPtr map, size_t b);
|
|
|
c1c534 |
|
|
|
c1c534 |
#endif
|
|
|
c1c534 |
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
|
|
|
c1c534 |
index 70426199ce..ef388757a7 100644
|
|
|
c1c534 |
--- a/src/util/virresctrl.c
|
|
|
c1c534 |
+++ b/src/util/virresctrl.c
|
|
|
c1c534 |
@@ -941,7 +941,8 @@ virResctrlAllocParseProcessCache(virResctrlInfoPtr resctrl,
|
|
|
c1c534 |
if (!mask)
|
|
|
c1c534 |
return -1;
|
|
|
c1c534 |
|
|
|
c1c534 |
- virBitmapShrink(mask, resctrl->levels[level]->types[type]->bits);
|
|
|
c1c534 |
+ if (virBitmapShrink(mask, resctrl->levels[level]->types[type]->bits) < 0)
|
|
|
c1c534 |
+ goto cleanup;
|
|
|
c1c534 |
|
|
|
c1c534 |
if (virResctrlAllocUpdateMask(alloc, level, type, cache_id, mask) < 0)
|
|
|
c1c534 |
goto cleanup;
|
|
|
c1c534 |
diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c
|
|
|
c1c534 |
index 5bf30b2b1c..a78e4da723 100644
|
|
|
c1c534 |
--- a/tests/virbitmaptest.c
|
|
|
c1c534 |
+++ b/tests/virbitmaptest.c
|
|
|
c1c534 |
@@ -656,6 +656,14 @@ test12(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
c1c534 |
|
|
|
c1c534 |
TEST_MAP(1024, "34,1023");
|
|
|
c1c534 |
|
|
|
c1c534 |
+ if (virBitmapShrink(map, 35) < 0)
|
|
|
c1c534 |
+ goto cleanup;
|
|
|
c1c534 |
+ TEST_MAP(35, "34");
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (virBitmapShrink(map, 34) < 0)
|
|
|
c1c534 |
+ goto cleanup;
|
|
|
c1c534 |
+ TEST_MAP(34, "");
|
|
|
c1c534 |
+
|
|
|
c1c534 |
ret = 0;
|
|
|
c1c534 |
|
|
|
c1c534 |
cleanup:
|
|
|
c1c534 |
--
|
|
|
c1c534 |
2.16.1
|
|
|
c1c534 |
|