]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
lib/test_vmalloc: add vrealloc test case
authorShivam Kalra <shivamkalra98@zohomail.in>
Tue, 19 May 2026 12:12:18 +0000 (17:42 +0530)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 2 Jun 2026 22:22:32 +0000 (15:22 -0700)
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>
lib/test_vmalloc.c

index 876c72c18a0cabdd85ced0dd205662bf5f307009..b23f85e8f8caec20283b7359e8a41da69026a187 100644 (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 @@ cleanup:
        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. */
 };