lib/test_vmalloc: add vrealloc test case

Introduce a new test case "vrealloc_test" that exercises the vrealloc()
shrink and in-place grow paths:

  - Grow beyond allocated pages (triggers full reallocation).
  - Shrink crossing a page boundary (frees tail pages).
  - Shrink within the same page (no page freeing).
  - Grow within the already allocated page count (in-place).

Data integrity is validated after each realloc step by checking that the
first byte of the original allocation is preserved.

The test is gated behind run_test_mask bit 12 (id 4096).

Link: https://lore.kernel.org/20260519-vmalloc-shrink-v14-5-70b96ee3e9c9@zohomail.in
Signed-off-by: Shivam Kalra <shivamkalra98@zohomail.in>
Reviewed-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
Cc: Alice Ryhl <aliceryhl@google.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Shivam Kalra
2026-05-19 17:42:18 +05:30
committed by Andrew Morton
parent 5ea8ec74c5
commit 3c3daeafcd

View File

@@ -55,6 +55,7 @@ __param(int, run_test_mask, 7,
"\t\tid: 512, name: kvfree_rcu_2_arg_vmalloc_test\n"
"\t\tid: 1024, name: vm_map_ram_test\n"
"\t\tid: 2048, name: no_block_alloc_test\n"
"\t\tid: 4096, name: vrealloc_test\n"
/* Add a new test case description here. */
);
@@ -421,6 +422,66 @@ vm_map_ram_test(void)
return nr_allocated != map_nr_pages;
}
static int vrealloc_test(void)
{
void *ptr, *tmp;
int i;
for (i = 0; i < test_loop_count; i++) {
int err = -1;
ptr = vrealloc(NULL, PAGE_SIZE, GFP_KERNEL);
if (!ptr)
return -1;
*((__u8 *)ptr) = 'a';
/* Grow: beyond allocated pages, triggers full realloc. */
tmp = vrealloc(ptr, 4 * PAGE_SIZE, GFP_KERNEL);
if (!tmp)
goto error;
ptr = tmp;
if (*((__u8 *)ptr) != 'a')
goto error;
/* Shrink: crosses page boundary, frees tail pages. */
tmp = vrealloc(ptr, PAGE_SIZE, GFP_KERNEL);
if (!tmp)
goto error;
ptr = tmp;
if (*((__u8 *)ptr) != 'a')
goto error;
/* Shrink: within same page, no page freeing. */
tmp = vrealloc(ptr, PAGE_SIZE / 2, GFP_KERNEL);
if (!tmp)
goto error;
ptr = tmp;
if (*((__u8 *)ptr) != 'a')
goto error;
/* Grow: within allocated page, in-place, no realloc. */
tmp = vrealloc(ptr, PAGE_SIZE, GFP_KERNEL);
if (!tmp)
goto error;
ptr = tmp;
if (*((__u8 *)ptr) != 'a')
goto error;
err = 0;
error:
vfree(ptr);
if (err)
return err;
}
return 0;
}
struct test_case_desc {
const char *test_name;
int (*test_func)(void);
@@ -440,6 +501,7 @@ static struct test_case_desc test_case_array[] = {
{ "kvfree_rcu_2_arg_vmalloc_test", kvfree_rcu_2_arg_vmalloc_test, },
{ "vm_map_ram_test", vm_map_ram_test, },
{ "no_block_alloc_test", no_block_alloc_test, true },
{ "vrealloc_test", vrealloc_test, },
/* Add a new test case here. */
};