aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@yandex-team.ru>2022-09-28 13:37:02 +0500
committerDave Barach <vpp@barachs.net>2023-03-19 12:17:23 +0000
commit8a4b79778f8b3149d663face83d37fbf96e12d05 (patch)
tree28a77bedaa359eecc075417cdc631dbedc7368b9
parentb9c8c57e983246ec034bc9059b1740558c951d51 (diff)
vppinfra: fix pool free bitmap allocation
Using clib_bitmap_vec_validate makes free bitmap vector to be x64 times bigger (assuming x86_64) than necessary when non-zero and possible oom due (u32)(0 - 1) math with zero alloc. Fix it with clib_bitmap_validate which takes bit size, not index and ensure at least one bit is allocated. Type: fix Change-Id: I7e191f4e2fb3722a06bb800e1d075f7c7e2dcec9 Signed-off-by: Vladislav Grishenko <themiron@yandex-team.ru>
-rw-r--r--src/vppinfra/CMakeLists.txt1
-rw-r--r--src/vppinfra/pool.h2
-rw-r--r--src/vppinfra/test_pool_alloc.c56
3 files changed, 58 insertions, 1 deletions
diff --git a/src/vppinfra/CMakeLists.txt b/src/vppinfra/CMakeLists.txt
index e24e0493ca9..204858d30a8 100644
--- a/src/vppinfra/CMakeLists.txt
+++ b/src/vppinfra/CMakeLists.txt
@@ -247,6 +247,7 @@ if(VPP_BUILD_VPPINFRA_TESTS)
macros
maplog
pmalloc
+ pool_alloc
pool_iterate
ptclosure
random
diff --git a/src/vppinfra/pool.h b/src/vppinfra/pool.h
index ea22af4a68b..968614e0b9d 100644
--- a/src/vppinfra/pool.h
+++ b/src/vppinfra/pool.h
@@ -333,7 +333,7 @@ _pool_alloc (void **pp, uword n_elts, uword align, void *heap, uword elt_sz)
ph = pool_header (pp[0]);
vec_resize (ph->free_indices, n_elts);
vec_dec_len (ph->free_indices, n_elts);
- clib_bitmap_vec_validate (ph->free_bitmap, len + n_elts - 1);
+ clib_bitmap_validate (ph->free_bitmap, (len + n_elts) ?: 1);
}
#define pool_alloc_aligned_heap(P, N, A, H) \
diff --git a/src/vppinfra/test_pool_alloc.c b/src/vppinfra/test_pool_alloc.c
new file mode 100644
index 00000000000..57b78b8ad9e
--- /dev/null
+++ b/src/vppinfra/test_pool_alloc.c
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright(c) 2023 Yandex LLC.
+ */
+
+#include <vppinfra/pool.h>
+
+/* can be a very large size */
+#define NELTS 1024
+
+int
+main (int argc, char *argv[])
+{
+ u32 *junk = 0;
+ int i;
+ u32 *tp = 0;
+ u32 *indices = 0;
+
+ clib_mem_init (0, 3ULL << 30);
+
+ vec_validate (indices, NELTS - 1);
+ vec_set_len (indices, 0);
+
+ /* zero size allocation is ok */
+ pool_alloc (tp, 0);
+
+ fformat (stdout, "%d pool elts of empty pool\n", pool_elts (tp));
+
+ pool_validate (tp);
+
+ pool_alloc (tp, NELTS);
+
+ for (i = 0; i < NELTS; i++)
+ {
+ pool_get (tp, junk);
+ vec_add1 (indices, junk - tp);
+ *junk = i;
+ }
+
+ for (i = 0; i < NELTS; i++)
+ {
+ junk = pool_elt_at_index (tp, indices[i]);
+ ASSERT (*junk == i);
+ }
+
+ fformat (stdout, "%d pool elts before deletes\n", pool_elts (tp));
+
+ pool_put_index (tp, indices[12]);
+ pool_put_index (tp, indices[43]);
+
+ fformat (stdout, "%d pool elts after deletes\n", pool_elts (tp));
+
+ pool_validate (tp);
+
+ pool_free (tp);
+ return 0;
+}