diff options
author | Vladislav Grishenko <themiron@yandex-team.ru> | 2022-09-28 13:37:02 +0500 |
---|---|---|
committer | Dave Barach <vpp@barachs.net> | 2023-03-19 12:17:23 +0000 |
commit | 8a4b79778f8b3149d663face83d37fbf96e12d05 (patch) | |
tree | 28a77bedaa359eecc075417cdc631dbedc7368b9 | |
parent | b9c8c57e983246ec034bc9059b1740558c951d51 (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.txt | 1 | ||||
-rw-r--r-- | src/vppinfra/pool.h | 2 | ||||
-rw-r--r-- | src/vppinfra/test_pool_alloc.c | 56 |
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; +} |