]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
mm/vmalloc: use physical page count for vrealloc() grow-in-place check
authorShivam Kalra <shivamkalra98@zohomail.in>
Tue, 19 May 2026 12:12:15 +0000 (17:42 +0530)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 2 Jun 2026 22:22:32 +0000 (15:22 -0700)
Update the grow-in-place check in vrealloc() to compare the requested size
against the actual physical page count (vm->nr_pages) rather than the
virtual area size (alloced_size, derived from get_vm_area_size()).

Currently both values are equivalent, but the upcoming vrealloc() shrink
functionality will free pages without reducing the virtual reservation
size.  After such a shrink, the old alloced_size-based comparison would
incorrectly allow a grow-in-place operation to succeed and attempt to
access freed pages.  Switch to vm->nr_pages now so the check remains
correct once shrink support is added.

Link: https://lore.kernel.org/20260519-vmalloc-shrink-v14-2-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>
mm/vmalloc.c

index 5555601b9529ca1f329b3d78edf600c7ced565e3..3e159b74cfab18901f2f0377cb9fb18d1f3040c6 100644 (file)
@@ -4343,6 +4343,12 @@ void *vrealloc_node_align_noprof(const void *p, size_t size, unsigned long align
                if (unlikely(flags & __GFP_THISNODE) && nid != NUMA_NO_NODE &&
                             nid != page_to_nid(vmalloc_to_page(p)))
                        goto need_realloc;
+       } else {
+               /*
+                * If p is NULL, vrealloc behaves exactly like vmalloc.
+                * Skip the shrink and in-place grow paths.
+                */
+               goto need_realloc;
        }
 
        /*
@@ -4361,7 +4367,7 @@ void *vrealloc_node_align_noprof(const void *p, size_t size, unsigned long align
        /*
         * We already have the bytes available in the allocation; use them.
         */
-       if (size <= alloced_size) {
+       if (size <= vm->nr_pages << PAGE_SHIFT) {
                /*
                 * No need to zero memory here, as unused memory will have
                 * already been zeroed at initial allocation time or during