From: Alice Ryhl <aliceryhl@google.com>
To: Shivam Kalra <shivamkalra98@zohomail.in>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Uladzislau Rezki <urezki@gmail.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Danilo Krummrich <dakr@kernel.org>
Subject: Re: [PATCH v5 2/3] mm/vmalloc: free unused pages on vrealloc() shrink
Date: Tue, 17 Mar 2026 14:39:01 +0000 [thread overview]
Message-ID: <ablnha2sgGUMO96d@google.com> (raw)
In-Reply-To: <20260317-vmalloc-shrink-v5-2-bbfbf54c5265@zohomail.in>
On Tue, Mar 17, 2026 at 01:47:34PM +0530, Shivam Kalra wrote:
> When vrealloc() shrinks an allocation and the new size crosses a page
> boundary, unmap and free the tail pages that are no longer needed. This
> reclaims physical memory that was previously wasted for the lifetime
> of the allocation.
>
> The heuristic is simple: always free when at least one full page becomes
> unused. Huge page allocations (page_order > 0) are skipped, as partial
> freeing would require splitting. Allocations with VM_FLUSH_RESET_PERMS
> are also skipped, as their direct-map permissions must be reset before
> pages are returned to the page allocator, which is handled by
> vm_reset_perms() during vfree().
>
> The virtual address reservation (vm->size / vmap_area) is intentionally
> kept unchanged, preserving the address for potential future grow-in-place
> support.
>
> Fix the grow-in-place check to compare against vm->nr_pages rather than
> get_vm_area_size(), since the latter reflects the virtual reservation
> which does not shrink. Without this fix, a grow after shrink would
> access freed pages.
>
> Signed-off-by: Shivam Kalra <shivamkalra98@zohomail.in>
> ---
> mm/vmalloc.c | 20 +++++++++++++++-----
> 1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index b29bf58c0e3f..f3820c6712c1 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -4345,14 +4345,24 @@ void *vrealloc_node_align_noprof(const void *p, size_t size, unsigned long align
> goto need_realloc;
> }
>
> - /*
> - * TODO: Shrink the vm_area, i.e. unmap and free unused pages. What
> - * would be a good heuristic for when to shrink the vm_area?
> - */
> if (size <= old_size) {
> + unsigned int new_nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
> +
> /* Zero out "freed" memory, potentially for future realloc. */
> if (want_init_on_free() || want_init_on_alloc(flags))
> memset((void *)p + size, 0, old_size - size);
> +
> + /* Free tail pages when shrink crosses a page boundary. */
> + if (new_nr_pages < vm->nr_pages && !vm_area_page_order(vm) &&
> + !(vm->flags & VM_FLUSH_RESET_PERMS)) {
> + unsigned long addr = (unsigned long)p;
> +
> + vunmap_range(addr + (new_nr_pages << PAGE_SHIFT),
> + addr + (vm->nr_pages << PAGE_SHIFT));
> +
> + vm_area_free_pages(vm, new_nr_pages, vm->nr_pages);
> + vm->nr_pages = new_nr_pages;
> + }
> vm->requested_size = size;
> kasan_vrealloc(p, old_size, size);
> return (void *)p;
> @@ -4361,7 +4371,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 <= (size_t)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
Hmm. So what happened here is that it has previously always been the
case that get_vm_area_size(area) == vm->nr_pages << PAGE_SHIFT, so these
constants were interchangable. But now that is no longer the case.
For example, 'remap_vmalloc_range_partial' compares the vm area size
with the range being mapped, and then proceeds to look up the pages and
map them. But now those pages may be missing.
I can't really tell if there are other places in this file that need to
be updated too.
Alice
next prev parent reply other threads:[~2026-03-17 14:39 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-17 8:17 [PATCH v5 0/3] mm/vmalloc: free unused pages on vrealloc() shrink Shivam Kalra
2026-03-17 8:17 ` Shivam Kalra via B4 Relay
2026-03-17 8:17 ` [PATCH v5 1/3] mm/vmalloc: extract vm_area_free_pages() helper from vfree() Shivam Kalra
2026-03-17 8:17 ` Shivam Kalra via B4 Relay
2026-03-17 14:16 ` Alice Ryhl
2026-03-18 17:53 ` Uladzislau Rezki
2026-03-20 9:42 ` Shivam Kalra
2026-03-21 8:02 ` Shivam Kalra
2026-03-17 8:17 ` [PATCH v5 2/3] mm/vmalloc: free unused pages on vrealloc() shrink Shivam Kalra
2026-03-17 8:17 ` Shivam Kalra via B4 Relay
2026-03-17 14:39 ` Alice Ryhl [this message]
2026-03-17 14:45 ` Danilo Krummrich
2026-03-17 16:01 ` Shivam Kalra
2026-03-17 8:17 ` [PATCH v5 3/3] lib/test_vmalloc: add vrealloc test case Shivam Kalra
2026-03-17 8:17 ` Shivam Kalra via B4 Relay
2026-03-17 21:11 ` [PATCH v5 0/3] mm/vmalloc: free unused pages on vrealloc() shrink Andrew Morton
2026-03-18 8:00 ` Shivam Kalra
2026-03-21 8:15 ` Shivam Kalra
2026-03-21 18:04 ` Andrew Morton
2026-03-22 12:48 ` Alice Ryhl
2026-03-22 14:32 ` Uladzislau Rezki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ablnha2sgGUMO96d@google.com \
--to=aliceryhl@google.com \
--cc=akpm@linux-foundation.org \
--cc=dakr@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=shivamkalra98@zohomail.in \
--cc=urezki@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.