* [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation
@ 2026-05-07 11:48 Jill Ravaliya
2026-05-07 11:48 ` [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing Jill Ravaliya
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Jill Ravaliya @ 2026-05-07 11:48 UTC (permalink / raw)
To: akpm, urezki; +Cc: linux-mm, linux-kernel, Jill Ravaliya
vrealloc() shrink path zeros unused memory and updates
vm->requested_size, but never frees the physical pages,
removes page table mappings, or flushes the TLB for the
unused range.
When a caller shrinks a vmalloc allocation, physical pages
backing the unused portion remain allocated until vfree()
is eventually called, wasting real RAM.
Fix this by unmapping the unused virtual range using
vunmap_range() which also flushes the TLB, freeing each
unused physical page back to the buddy allocator, and
updating vm->nr_pages to reflect the new page count.
Signed-off-by: Jill Ravaliya <jillravaliya@gmail.com>
---
mm/vmalloc.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index aa08651ec..a8cedfc5d 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -4336,6 +4336,27 @@ void *vrealloc_node_align_noprof(const void *p, size_t size, unsigned long align
memset((void *)p + size, 0, old_size - size);
vm->requested_size = size;
kasan_vrealloc(p, old_size, size);
+
+ /* Shrink the vm_area: unmap and free unused pages. */
+ if (size < alloced_size) {
+ unsigned long new_nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ unsigned long i;
+
+ /* Unmap unused virtual range and flush TLB. */
+ vunmap_range((unsigned long)p + PAGE_ALIGN(size),
+ (unsigned long)p + alloced_size);
+
+ /* Free unused physical pages back to buddy allocator. */
+ for (i = new_nr_pages; i < vm->nr_pages; i++) {
+ mod_lruvec_page_state(vm->pages[i],
+ NR_VMALLOC, -1);
+ __free_page(vm->pages[i]);
+ vm->pages[i] = NULL;
+ }
+
+ vm->nr_pages = new_nr_pages;
+ }
+
return (void *)p;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing
2026-05-07 11:48 [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation Jill Ravaliya
@ 2026-05-07 11:48 ` Jill Ravaliya
2026-05-23 13:34 ` kernel test robot
2026-05-23 16:20 ` Uladzislau Rezki
2026-05-07 17:17 ` [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation Uladzislau Rezki
2026-05-07 20:26 ` [syzbot ci] " syzbot ci
2 siblings, 2 replies; 7+ messages in thread
From: Jill Ravaliya @ 2026-05-07 11:48 UTC (permalink / raw)
To: akpm, urezki; +Cc: linux-mm, linux-kernel, Jill Ravaliya
Add a selftest that verifies vrealloc() frees physical pages
when shrinking an allocation.
The test loads a kernel module that:
1. Allocates 10MB with vmalloc()
2. Touches all pages to force physical allocation
3. Shrinks to 2MB with vrealloc()
4. Verifies free page count increased after shrink
Without the fix, the test fails because no pages are freed.
With the fix applied, the test passes confirming ~2048 pages
are returned to the system after shrinking from 10MB to 2MB.
Tested on kernel 7.0.0 in QEMU.
Signed-off-by: Jill Ravaliya <jillravaliya@gmail.com>
---
tools/testing/selftests/mm/Makefile | 5 ++
.../selftests/mm/vrealloc_shrink_test.c | 65 +++++++++++++++++++
2 files changed, 70 insertions(+)
create mode 100644 tools/testing/selftests/mm/vrealloc_shrink_test.c
diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index cd24596cd..4eab7c76c 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -104,6 +104,7 @@ TEST_GEN_FILES += hugetlb_dio
TEST_GEN_FILES += droppable
TEST_GEN_FILES += guard-regions
TEST_GEN_FILES += merge
+TEST_GEN_FILES += vrealloc_shrink_test
TEST_GEN_FILES += rmap
TEST_GEN_FILES += folio_split_race_test
@@ -282,3 +283,7 @@ warn_missing_page_frag:
echo "Warning: $(PAGE_FRAG_WARNING). page_frag test will be skipped." ; \
echo
endif
+
+# vrealloc shrink test module
+vrealloc_shrink_mod.ko: vrealloc_shrink_mod.c
+ $(MAKE) -C $(KDIR) M=$(PWD) modules
diff --git a/tools/testing/selftests/mm/vrealloc_shrink_test.c b/tools/testing/selftests/mm/vrealloc_shrink_test.c
new file mode 100644
index 000000000..cf4263074
--- /dev/null
+++ b/tools/testing/selftests/mm/vrealloc_shrink_test.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test that vrealloc() frees physical pages when shrinking.
+ *
+ * vrealloc() shrink path previously zeroed unused memory and updated
+ * vm->requested_size, but never freed the physical pages backing the
+ * unused portion of the allocation. This test verifies the fix by
+ * loading a kernel module that directly measures nr_pages before and
+ * after vrealloc() shrink.
+ *
+ * Copyright (C) 2026 Jill Ravaliya
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "../kselftest.h"
+
+#define MODULE_NAME "vrealloc_shrink_mod"
+#define DMESG_PASS "vrealloc_shrink: PASS"
+#define DMESG_FAIL "vrealloc_shrink: FAIL"
+
+static int run_cmd(const char *cmd)
+{
+ return system(cmd);
+}
+
+static int check_dmesg_for(const char *pattern)
+{
+ char cmd[256];
+ snprintf(cmd, sizeof(cmd),
+ "dmesg | grep -q '%s'", pattern);
+ return system(cmd) == 0;
+}
+
+int main(void)
+{
+ ksft_print_header();
+ ksft_set_plan(1);
+
+ /* Insert the test module */
+ if (run_cmd("insmod " MODULE_NAME ".ko") != 0) {
+ ksft_test_result_skip(
+ "could not load %s.ko - is it built?\n",
+ MODULE_NAME);
+ ksft_finished();
+ }
+
+ /* Check dmesg for pass/fail */
+ if (check_dmesg_for(DMESG_PASS)) {
+ ksft_test_result_pass(
+ "vrealloc shrink frees physical pages\n");
+ } else if (check_dmesg_for(DMESG_FAIL)) {
+ ksft_test_result_fail(
+ "vrealloc shrink did NOT free physical pages\n");
+ } else {
+ ksft_test_result_fail(
+ "could not find test result in dmesg\n");
+ }
+
+ run_cmd("rmmod " MODULE_NAME);
+ ksft_finished();
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation
2026-05-07 11:48 [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation Jill Ravaliya
2026-05-07 11:48 ` [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing Jill Ravaliya
@ 2026-05-07 17:17 ` Uladzislau Rezki
2026-05-07 20:26 ` [syzbot ci] " syzbot ci
2 siblings, 0 replies; 7+ messages in thread
From: Uladzislau Rezki @ 2026-05-07 17:17 UTC (permalink / raw)
To: Jill Ravaliya; +Cc: akpm, urezki, linux-mm, linux-kernel, Shivam Kalra
On Thu, May 07, 2026 at 05:18:53PM +0530, Jill Ravaliya wrote:
> vrealloc() shrink path zeros unused memory and updates
> vm->requested_size, but never frees the physical pages,
> removes page table mappings, or flushes the TLB for the
> unused range.
>
> When a caller shrinks a vmalloc allocation, physical pages
> backing the unused portion remain allocated until vfree()
> is eventually called, wasting real RAM.
>
> Fix this by unmapping the unused virtual range using
> vunmap_range() which also flushes the TLB, freeing each
> unused physical page back to the buddy allocator, and
> updating vm->nr_pages to reflect the new page count.
>
> Signed-off-by: Jill Ravaliya <jillravaliya@gmail.com>
> ---
> mm/vmalloc.c | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index aa08651ec..a8cedfc5d 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -4336,6 +4336,27 @@ void *vrealloc_node_align_noprof(const void *p, size_t size, unsigned long align
> memset((void *)p + size, 0, old_size - size);
> vm->requested_size = size;
> kasan_vrealloc(p, old_size, size);
> +
> + /* Shrink the vm_area: unmap and free unused pages. */
> + if (size < alloced_size) {
> + unsigned long new_nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
> + unsigned long i;
> +
> + /* Unmap unused virtual range and flush TLB. */
> + vunmap_range((unsigned long)p + PAGE_ALIGN(size),
> + (unsigned long)p + alloced_size);
> +
> + /* Free unused physical pages back to buddy allocator. */
> + for (i = new_nr_pages; i < vm->nr_pages; i++) {
> + mod_lruvec_page_state(vm->pages[i],
> + NR_VMALLOC, -1);
> + __free_page(vm->pages[i]);
> + vm->pages[i] = NULL;
> + }
> +
> + vm->nr_pages = new_nr_pages;
> + }
> +
> return (void *)p;
> }
>
> --
> 2.43.0
>
There is already work to address this: https://lore.kernel.org/all/20260428-vmalloc-shrink-v12-0-3c18c9172eb1@zohomail.in/
--
Uladzislau Rezki
^ permalink raw reply [flat|nested] 7+ messages in thread
* [syzbot ci] Re: mm/vmalloc: free unused pages when shrinking vrealloc() allocation
2026-05-07 11:48 [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation Jill Ravaliya
2026-05-07 11:48 ` [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing Jill Ravaliya
2026-05-07 17:17 ` [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation Uladzislau Rezki
@ 2026-05-07 20:26 ` syzbot ci
2 siblings, 0 replies; 7+ messages in thread
From: syzbot ci @ 2026-05-07 20:26 UTC (permalink / raw)
To: akpm, jillravaliya, linux-kernel, linux-mm, urezki; +Cc: syzbot, syzkaller-bugs
syzbot ci has tested the following series
[v1] mm/vmalloc: free unused pages when shrinking vrealloc() allocation
https://lore.kernel.org/all/20260507114854.41117-1-jillravaliya@gmail.com
* [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation
* [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing
and found the following issue:
kernel BUG in __vunmap_range_noflush
Full report is available here:
https://ci.syzbot.org/series/13b0874e-a9f8-4992-be93-e93cc88e5e44
***
kernel BUG in __vunmap_range_noflush
tree: torvalds
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
base: 2c340aab5485ebe9e33c01437dd4815ef33c8df5
arch: amd64
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
config: https://ci.syzbot.org/builds/625f7138-9b20-4205-b0e7-02ed1219bd31/config
syz repro: https://ci.syzbot.org/findings/13e8dc07-d697-4345-a27f-319e9c1fe3d6/syz_repro
------------[ cut here ]------------
kernel BUG at mm/vmalloc.c:488!
Oops: invalid opcode: 0000 [#1] SMP KASAN PTI
CPU: 1 UID: 0 PID: 5824 Comm: syz.2.19 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
RIP: 0010:__vunmap_range_noflush+0xb4d/0xb70 mm/vmalloc.c:488
Code: 00 e9 64 f5 ff ff e8 12 8d a6 ff 48 c7 c7 a0 0e a8 8e 48 8b 74 24 48 48 89 da e8 0e c5 cf 02 e9 67 f5 ff ff e8 f4 8c a6 ff 90 <0f> 0b e8 ec 8c a6 ff e9 53 ff ff ff e8 e2 8c a6 ff bb 02 00 00 00
RSP: 0018:ffffc90003b575e0 EFLAGS: 00010293
RAX: ffffffff821f16bc RBX: ffffc900036fa000 RCX: ffff8881072a1d80
RDX: 0000000000000000 RSI: ffffc900036fa000 RDI: ffffc900036fa000
RBP: ffff88816ebb3980 R08: ffff88810007f1bb R09: 0000000000000000
R10: ffffc900036f9bb0 R11: ffffed102000fe38 R12: 0000000000000001
R13: ffffc900036fa000 R14: ffffc900036fa000 R15: dffffc0000000000
FS: 00007f4d6b8c46c0(0000) GS:ffff8882a9293000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055924f0dd8c0 CR3: 00000001057f2000 CR4: 00000000000006f0
Call Trace:
<TASK>
vunmap_range_noflush mm/vmalloc.c:506 [inline]
vunmap_range mm/vmalloc.c:521 [inline]
vrealloc_node_align_noprof+0x4fc/0x880 mm/vmalloc.c:4346
bpf_patch_insn_data+0xeb/0x10a0 kernel/bpf/fixups.c:254
bpf_convert_ctx_accesses+0x213f/0x2d70 kernel/bpf/fixups.c:974
bpf_check+0x2b8e/0x49f0 kernel/bpf/verifier.c:20094
bpf_prog_load+0x1406/0x1a10 kernel/bpf/syscall.c:3082
__sys_bpf+0x618/0x950 kernel/bpf/syscall.c:6248
__do_sys_bpf kernel/bpf/syscall.c:6361 [inline]
__se_sys_bpf kernel/bpf/syscall.c:6359 [inline]
__x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:6359
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f4d6a99cdd9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f4d6b8c4028 EFLAGS: 00000246 ORIG_RAX: 0000000000000141
RAX: ffffffffffffffda RBX: 00007f4d6ac15fa0 RCX: 00007f4d6a99cdd9
RDX: 0000000000000048 RSI: 00002000000054c0 RDI: 0000000000000005
RBP: 00007f4d6aa32d69 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f4d6ac16038 R14: 00007f4d6ac15fa0 R15: 00007ffff714fc08
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:__vunmap_range_noflush+0xb4d/0xb70 mm/vmalloc.c:488
Code: 00 e9 64 f5 ff ff e8 12 8d a6 ff 48 c7 c7 a0 0e a8 8e 48 8b 74 24 48 48 89 da e8 0e c5 cf 02 e9 67 f5 ff ff e8 f4 8c a6 ff 90 <0f> 0b e8 ec 8c a6 ff e9 53 ff ff ff e8 e2 8c a6 ff bb 02 00 00 00
RSP: 0018:ffffc90003b575e0 EFLAGS: 00010293
RAX: ffffffff821f16bc RBX: ffffc900036fa000 RCX: ffff8881072a1d80
RDX: 0000000000000000 RSI: ffffc900036fa000 RDI: ffffc900036fa000
RBP: ffff88816ebb3980 R08: ffff88810007f1bb R09: 0000000000000000
R10: ffffc900036f9bb0 R11: ffffed102000fe38 R12: 0000000000000001
R13: ffffc900036fa000 R14: ffffc900036fa000 R15: dffffc0000000000
FS: 00007f4d6b8c46c0(0000) GS:ffff8882a9293000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffdaf55afd8 CR3: 00000001057f2000 CR4: 00000000000006f0
***
If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
Tested-by: syzbot@syzkaller.appspotmail.com
---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.
To test a patch for this bug, please reply with `#syz test`
(should be on a separate line).
The patch should be attached to the email.
Note: arguments like custom git repos and branches are not supported.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing
2026-05-07 11:48 ` [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing Jill Ravaliya
@ 2026-05-23 13:34 ` kernel test robot
2026-05-23 16:20 ` Uladzislau Rezki
1 sibling, 0 replies; 7+ messages in thread
From: kernel test robot @ 2026-05-23 13:34 UTC (permalink / raw)
To: Jill Ravaliya
Cc: oe-lkp, lkp, linux-mm, akpm, urezki, linux-kernel, Jill Ravaliya
Hello,
kernel test robot noticed "kernel_BUG_at_mm/vmalloc.c" on:
commit: 7a2723bc6f2ec12f6e8bfccdf20c09b84f721993 ("[PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing")
url: https://github.com/intel-lab-lkp/linux/commits/Jill-Ravaliya/selftests-mm-add-test-for-vrealloc-shrink-page-freeing/20260511-181706
base: https://git.kernel.org/cgit/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/all/20260507114854.41117-2-jillravaliya@gmail.com/
patch subject: [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing
in testcase: boot
config: x86_64-kexec
compiler: clang-20
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 32G
(please refer to attached dmesg/kmsg for entire log/backtrace)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202605231524.731e5313-lkp@intel.com
[ 3.859842][ T1] ------------[ cut here ]------------
[ 3.860491][ T1] kernel BUG at mm/vmalloc.c:488!
[ 3.861026][ T1] Oops: invalid opcode: 0000 [#1] SMP PTI
[ 3.861616][ T1] CPU: 0 UID: 0 PID: 1 Comm: systemd Not tainted 7.1.0-rc1-00283-g7a2723bc6f2e #1 PREEMPT(lazy)
[ 3.862702][ T1] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 3.863724][ T1] RIP: 0010:__vunmap_range_noflush (vmalloc.c:501)
[ 3.864346][ T1] Code: 7c 24 10 48 83 c4 58 5b 41 5c 41 5d 41 5e 41 5f 5d e9 7c 9d d2 ff 48 83 c4 58 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc <0f> 0b 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 80 00 00
All code
========
0: 7c 24 jl 0x26
2: 10 48 83 adc %cl,-0x7d(%rax)
5: c4 (bad)
6: 58 pop %rax
7: 5b pop %rbx
8: 41 5c pop %r12
a: 41 5d pop %r13
c: 41 5e pop %r14
e: 41 5f pop %r15
10: 5d pop %rbp
11: e9 7c 9d d2 ff jmp 0xffffffffffd29d92
16: 48 83 c4 58 add $0x58,%rsp
1a: 5b pop %rbx
1b: 41 5c pop %r12
1d: 41 5d pop %r13
1f: 41 5e pop %r14
21: 41 5f pop %r15
23: 5d pop %rbp
24: c3 ret
25: cc int3
26: cc int3
27: cc int3
28: cc int3
29: cc int3
2a:* 0f 0b ud2 <-- trapping instruction
2c: 66 66 66 66 66 66 2e data16 data16 data16 data16 data16 cs nopw 0x0(%rax,%rax,1)
33: 0f 1f 84 00 00 00 00
3a: 00
3b: 0f .byte 0xf
3c: 1f (bad)
3d: 80 00 00 addb $0x0,(%rax)
Code starting with the faulting instruction
===========================================
0: 0f 0b ud2
2: 66 66 66 66 66 66 2e data16 data16 data16 data16 data16 cs nopw 0x0(%rax,%rax,1)
9: 0f 1f 84 00 00 00 00
10: 00
11: 0f .byte 0xf
12: 1f (bad)
13: 80 00 00 addb $0x0,(%rax)
[ 3.866197][ T1] RSP: 0018:ffffc90000013a70 EFLAGS: 00010246
[ 3.866816][ T1] RAX: ffffc90000035990 RBX: ffffc90000035000 RCX: 0000000000000000
[ 3.867632][ T1] RDX: 0000000000000000 RSI: ffffc90000036000 RDI: ffffc90000036000
[ 3.868442][ T1] RBP: 0000000000400dc0 R08: 00000000ffffffff R09: 0000000000000000
[ 3.869260][ T1] R10: ffffc90000035990 R11: ffffffff8215b050 R12: ffffc90000036000
[ 3.870088][ T1] R13: ffffc90000036000 R14: 0000000000000001 R15: ffff88810f5e18a0
[ 3.870907][ T1] FS: 00007f356fcade40(0000) GS:ffff88889c100000(0000) knlGS:0000000000000000
[ 3.871802][ T1] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 3.872461][ T1] CR2: 00007f3570966000 CR3: 000000010c872000 CR4: 00000000000406f0
[ 3.873270][ T1] Call Trace:
[ 3.873666][ T1] <TASK>
[ 3.874083][ T1] ? krealloc_node_align_noprof (slub.c:?)
[ 3.874811][ T1] ? find_instance (bpf/liveness.c:66)
[ 3.875300][ T1] vrealloc_node_align_noprof (vmalloc.c:506 vmalloc.c:521 vmalloc.c:4345)
[ 3.875883][ T1] bpf_patch_insn_data (bpf/fixups.c:254)
[ 3.876410][ T1] bpf_convert_ctx_accesses (bpf/fixups.c:974)
[ 3.876975][ T1] bpf_check (bpf/verifier.c:20094)
[ 3.877441][ T1] bpf_prog_load (bpf/syscall.c:3082)
[ 3.877951][ T1] __sys_bpf (bpf/syscall.c:6248)
[ 3.878419][ T1] __x64_sys_bpf (bpf/syscall.c:6361 bpf/syscall.c:6359 bpf/syscall.c:6359)
[ 3.878891][ T1] do_syscall_64 (x86/entry/syscall_64.c:63 x86/entry/syscall_64.c:94)
[ 3.879373][ T1] entry_SYSCALL_64_after_hwframe (x86/entry/entry_64.S:121)
[ 3.879974][ T1] RIP: 0033:0x7f3570834779
[ 3.880451][ T1] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 4f 86 0d 00 f7 d8 64 89 01 48
All code
========
0: ff c3 inc %ebx
2: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
9: 00 00 00
c: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
11: 48 89 f8 mov %rdi,%rax
14: 48 89 f7 mov %rsi,%rdi
17: 48 89 d6 mov %rdx,%rsi
1a: 48 89 ca mov %rcx,%rdx
1d: 4d 89 c2 mov %r8,%r10
20: 4d 89 c8 mov %r9,%r8
23: 4c 8b 4c 24 08 mov 0x8(%rsp),%r9
28: 0f 05 syscall
2a:* 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax <-- trapping instruction
30: 73 01 jae 0x33
32: c3 ret
33: 48 8b 0d 4f 86 0d 00 mov 0xd864f(%rip),%rcx # 0xd8689
3a: f7 d8 neg %eax
3c: 64 89 01 mov %eax,%fs:(%rcx)
3f: 48 rex.W
Code starting with the faulting instruction
===========================================
0: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
6: 73 01 jae 0x9
8: c3 ret
9: 48 8b 0d 4f 86 0d 00 mov 0xd864f(%rip),%rcx # 0xd865f
10: f7 d8 neg %eax
12: 64 89 01 mov %eax,%fs:(%rcx)
15: 48 rex.W
[ 3.882300][ T1] RSP: 002b:00007ffcd8cbbc88 EFLAGS: 00000246 ORIG_RAX: 0000000000000141
[ 3.883149][ T1] RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 00007f3570834779
[ 3.883966][ T1] RDX: 0000000000000094 RSI: 00007ffcd8cbbd10 RDI: 0000000000000005
[ 3.884774][ T1] RBP: 0000000000000013 R08: 00007ffcd8cbbe40 R09: 0000559a2fc27b30
[ 3.885594][ T1] R10: 0000000000000013 R11: 0000000000000246 R12: 0000000000000094
[ 3.886456][ T1] R13: 00007ffcd8cbbd10 R14: 00007ffcd8cbbd10 R15: 0000000000000008
[ 3.887273][ T1] </TASK>
[ 3.887627][ T1] Modules linked in:
[ 3.888071][ T1] ---[ end trace 0000000000000000 ]---
[ 3.888642][ T1] RIP: 0010:__vunmap_range_noflush (vmalloc.c:501)
[ 3.889273][ T1] Code: 7c 24 10 48 83 c4 58 5b 41 5c 41 5d 41 5e 41 5f 5d e9 7c 9d d2 ff 48 83 c4 58 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc <0f> 0b 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 80 00 00
All code
========
0: 7c 24 jl 0x26
2: 10 48 83 adc %cl,-0x7d(%rax)
5: c4 (bad)
6: 58 pop %rax
7: 5b pop %rbx
8: 41 5c pop %r12
a: 41 5d pop %r13
c: 41 5e pop %r14
e: 41 5f pop %r15
10: 5d pop %rbp
11: e9 7c 9d d2 ff jmp 0xffffffffffd29d92
16: 48 83 c4 58 add $0x58,%rsp
1a: 5b pop %rbx
1b: 41 5c pop %r12
1d: 41 5d pop %r13
1f: 41 5e pop %r14
21: 41 5f pop %r15
23: 5d pop %rbp
24: c3 ret
25: cc int3
26: cc int3
27: cc int3
28: cc int3
29: cc int3
2a:* 0f 0b ud2 <-- trapping instruction
2c: 66 66 66 66 66 66 2e data16 data16 data16 data16 data16 cs nopw 0x0(%rax,%rax,1)
33: 0f 1f 84 00 00 00 00
3a: 00
3b: 0f .byte 0xf
3c: 1f (bad)
3d: 80 00 00 addb $0x0,(%rax)
Code starting with the faulting instruction
===========================================
0: 0f 0b ud2
2: 66 66 66 66 66 66 2e data16 data16 data16 data16 data16 cs nopw 0x0(%rax,%rax,1)
9: 0f 1f 84 00 00 00 00
10: 00
11: 0f .byte 0xf
12: 1f (bad)
13: 80 00 00 addb $0x0,(%rax)
The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20260523/202605231524.731e5313-lkp@intel.com
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing
2026-05-07 11:48 ` [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing Jill Ravaliya
2026-05-23 13:34 ` kernel test robot
@ 2026-05-23 16:20 ` Uladzislau Rezki
2026-05-24 2:53 ` Jill Ravaliya
1 sibling, 1 reply; 7+ messages in thread
From: Uladzislau Rezki @ 2026-05-23 16:20 UTC (permalink / raw)
To: Jill Ravaliya; +Cc: akpm, urezki, linux-mm, linux-kernel
On Thu, May 07, 2026 at 05:18:54PM +0530, Jill Ravaliya wrote:
> Add a selftest that verifies vrealloc() frees physical pages
> when shrinking an allocation.
>
> The test loads a kernel module that:
> 1. Allocates 10MB with vmalloc()
> 2. Touches all pages to force physical allocation
> 3. Shrinks to 2MB with vrealloc()
> 4. Verifies free page count increased after shrink
>
> Without the fix, the test fails because no pages are freed.
> With the fix applied, the test passes confirming ~2048 pages
> are returned to the system after shrinking from 10MB to 2MB.
>
> Tested on kernel 7.0.0 in QEMU.
>
> Signed-off-by: Jill Ravaliya <jillravaliya@gmail.com>
> ---
> tools/testing/selftests/mm/Makefile | 5 ++
> .../selftests/mm/vrealloc_shrink_test.c | 65 +++++++++++++++++++
> 2 files changed, 70 insertions(+)
> create mode 100644 tools/testing/selftests/mm/vrealloc_shrink_test.c
>
> diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
> index cd24596cd..4eab7c76c 100644
> --- a/tools/testing/selftests/mm/Makefile
> +++ b/tools/testing/selftests/mm/Makefile
> @@ -104,6 +104,7 @@ TEST_GEN_FILES += hugetlb_dio
> TEST_GEN_FILES += droppable
> TEST_GEN_FILES += guard-regions
> TEST_GEN_FILES += merge
> +TEST_GEN_FILES += vrealloc_shrink_test
> TEST_GEN_FILES += rmap
> TEST_GEN_FILES += folio_split_race_test
>
> @@ -282,3 +283,7 @@ warn_missing_page_frag:
> echo "Warning: $(PAGE_FRAG_WARNING). page_frag test will be skipped." ; \
> echo
> endif
> +
> +# vrealloc shrink test module
> +vrealloc_shrink_mod.ko: vrealloc_shrink_mod.c
> + $(MAKE) -C $(KDIR) M=$(PWD) modules
> diff --git a/tools/testing/selftests/mm/vrealloc_shrink_test.c b/tools/testing/selftests/mm/vrealloc_shrink_test.c
> new file mode 100644
> index 000000000..cf4263074
> --- /dev/null
> +++ b/tools/testing/selftests/mm/vrealloc_shrink_test.c
> @@ -0,0 +1,65 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Test that vrealloc() frees physical pages when shrinking.
> + *
> + * vrealloc() shrink path previously zeroed unused memory and updated
> + * vm->requested_size, but never freed the physical pages backing the
> + * unused portion of the allocation. This test verifies the fix by
> + * loading a kernel module that directly measures nr_pages before and
> + * after vrealloc() shrink.
> + *
> + * Copyright (C) 2026 Jill Ravaliya
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include "../kselftest.h"
> +
> +#define MODULE_NAME "vrealloc_shrink_mod"
> +#define DMESG_PASS "vrealloc_shrink: PASS"
> +#define DMESG_FAIL "vrealloc_shrink: FAIL"
> +
> +static int run_cmd(const char *cmd)
> +{
> + return system(cmd);
> +}
> +
> +static int check_dmesg_for(const char *pattern)
> +{
> + char cmd[256];
> + snprintf(cmd, sizeof(cmd),
> + "dmesg | grep -q '%s'", pattern);
> + return system(cmd) == 0;
> +}
> +
> +int main(void)
> +{
> + ksft_print_header();
> + ksft_set_plan(1);
> +
> + /* Insert the test module */
> + if (run_cmd("insmod " MODULE_NAME ".ko") != 0) {
> + ksft_test_result_skip(
> + "could not load %s.ko - is it built?\n",
> + MODULE_NAME);
> + ksft_finished();
> + }
> +
> + /* Check dmesg for pass/fail */
> + if (check_dmesg_for(DMESG_PASS)) {
> + ksft_test_result_pass(
> + "vrealloc shrink frees physical pages\n");
> + } else if (check_dmesg_for(DMESG_FAIL)) {
> + ksft_test_result_fail(
> + "vrealloc shrink did NOT free physical pages\n");
> + } else {
> + ksft_test_result_fail(
> + "could not find test result in dmesg\n");
> + }
> +
> + run_cmd("rmmod " MODULE_NAME);
> + ksft_finished();
> +}
> --
> 2.43.0
>
We have a test case that covers vrealloc() functionality. See test_vmalloc.c
file.
--
Uladzislau Rezki
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing
2026-05-23 16:20 ` Uladzislau Rezki
@ 2026-05-24 2:53 ` Jill Ravaliya
0 siblings, 0 replies; 7+ messages in thread
From: Jill Ravaliya @ 2026-05-24 2:53 UTC (permalink / raw)
To: Uladzislau Rezki; +Cc: akpm, linux-mm, linux-kernel
Hey Uladzislau,
Thanks for pointing that out. I'll check test_vmalloc.c right away.
Jill
On Sat, May 23, 2026 at 9:50 PM Uladzislau Rezki <urezki@gmail.com> wrote:
>
> On Thu, May 07, 2026 at 05:18:54PM +0530, Jill Ravaliya wrote:
> > Add a selftest that verifies vrealloc() frees physical pages
> > when shrinking an allocation.
> >
> > The test loads a kernel module that:
> > 1. Allocates 10MB with vmalloc()
> > 2. Touches all pages to force physical allocation
> > 3. Shrinks to 2MB with vrealloc()
> > 4. Verifies free page count increased after shrink
> >
> > Without the fix, the test fails because no pages are freed.
> > With the fix applied, the test passes confirming ~2048 pages
> > are returned to the system after shrinking from 10MB to 2MB.
> >
> > Tested on kernel 7.0.0 in QEMU.
> >
> > Signed-off-by: Jill Ravaliya <jillravaliya@gmail.com>
> > ---
> > tools/testing/selftests/mm/Makefile | 5 ++
> > .../selftests/mm/vrealloc_shrink_test.c | 65 +++++++++++++++++++
> > 2 files changed, 70 insertions(+)
> > create mode 100644 tools/testing/selftests/mm/vrealloc_shrink_test.c
> >
> > diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
> > index cd24596cd..4eab7c76c 100644
> > --- a/tools/testing/selftests/mm/Makefile
> > +++ b/tools/testing/selftests/mm/Makefile
> > @@ -104,6 +104,7 @@ TEST_GEN_FILES += hugetlb_dio
> > TEST_GEN_FILES += droppable
> > TEST_GEN_FILES += guard-regions
> > TEST_GEN_FILES += merge
> > +TEST_GEN_FILES += vrealloc_shrink_test
> > TEST_GEN_FILES += rmap
> > TEST_GEN_FILES += folio_split_race_test
> >
> > @@ -282,3 +283,7 @@ warn_missing_page_frag:
> > echo "Warning: $(PAGE_FRAG_WARNING). page_frag test will be skipped." ; \
> > echo
> > endif
> > +
> > +# vrealloc shrink test module
> > +vrealloc_shrink_mod.ko: vrealloc_shrink_mod.c
> > + $(MAKE) -C $(KDIR) M=$(PWD) modules
> > diff --git a/tools/testing/selftests/mm/vrealloc_shrink_test.c b/tools/testing/selftests/mm/vrealloc_shrink_test.c
> > new file mode 100644
> > index 000000000..cf4263074
> > --- /dev/null
> > +++ b/tools/testing/selftests/mm/vrealloc_shrink_test.c
> > @@ -0,0 +1,65 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Test that vrealloc() frees physical pages when shrinking.
> > + *
> > + * vrealloc() shrink path previously zeroed unused memory and updated
> > + * vm->requested_size, but never freed the physical pages backing the
> > + * unused portion of the allocation. This test verifies the fix by
> > + * loading a kernel module that directly measures nr_pages before and
> > + * after vrealloc() shrink.
> > + *
> > + * Copyright (C) 2026 Jill Ravaliya
> > + */
> > +
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <unistd.h>
> > +#include <fcntl.h>
> > +#include "../kselftest.h"
> > +
> > +#define MODULE_NAME "vrealloc_shrink_mod"
> > +#define DMESG_PASS "vrealloc_shrink: PASS"
> > +#define DMESG_FAIL "vrealloc_shrink: FAIL"
> > +
> > +static int run_cmd(const char *cmd)
> > +{
> > + return system(cmd);
> > +}
> > +
> > +static int check_dmesg_for(const char *pattern)
> > +{
> > + char cmd[256];
> > + snprintf(cmd, sizeof(cmd),
> > + "dmesg | grep -q '%s'", pattern);
> > + return system(cmd) == 0;
> > +}
> > +
> > +int main(void)
> > +{
> > + ksft_print_header();
> > + ksft_set_plan(1);
> > +
> > + /* Insert the test module */
> > + if (run_cmd("insmod " MODULE_NAME ".ko") != 0) {
> > + ksft_test_result_skip(
> > + "could not load %s.ko - is it built?\n",
> > + MODULE_NAME);
> > + ksft_finished();
> > + }
> > +
> > + /* Check dmesg for pass/fail */
> > + if (check_dmesg_for(DMESG_PASS)) {
> > + ksft_test_result_pass(
> > + "vrealloc shrink frees physical pages\n");
> > + } else if (check_dmesg_for(DMESG_FAIL)) {
> > + ksft_test_result_fail(
> > + "vrealloc shrink did NOT free physical pages\n");
> > + } else {
> > + ksft_test_result_fail(
> > + "could not find test result in dmesg\n");
> > + }
> > +
> > + run_cmd("rmmod " MODULE_NAME);
> > + ksft_finished();
> > +}
> > --
> > 2.43.0
> >
> We have a test case that covers vrealloc() functionality. See test_vmalloc.c
> file.
>
> --
> Uladzislau Rezki
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-05-24 2:53 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-07 11:48 [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation Jill Ravaliya
2026-05-07 11:48 ` [PATCH 2/2] selftests/mm: add test for vrealloc() shrink page freeing Jill Ravaliya
2026-05-23 13:34 ` kernel test robot
2026-05-23 16:20 ` Uladzislau Rezki
2026-05-24 2:53 ` Jill Ravaliya
2026-05-07 17:17 ` [PATCH 1/2] mm/vmalloc: free unused pages when shrinking vrealloc() allocation Uladzislau Rezki
2026-05-07 20:26 ` [syzbot ci] " syzbot ci
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox