Skip to contentSkip to conversation

mm/vmalloc: implement in-place grow for vrealloc

RFC PATCH New Ye Liu 1 participant 1 message Sep 15

Subsystems (2)
lore
Share & tools
lore

Ye Liu

author
#0 lore raw

RFC PATCH 1/1 mm/vmalloc: implement in-place grow for vrealloc

From: Ye Liu <[email protected]>

vrealloc() previously fell through to a full reallocation + memcpy + vfree whenever the new size exceeded the already-mapped page count, even when the existing VA range had sufficient room. This meant every grow operation paid an O(n) memcpy and two VA allocations for no benefit.

Implement an in-place grow path that allocates additional physical pages and maps them into the unused tail of the existing VA range, avoiding reallocation entirely when the VA has room. On failure (partial allocation or mapping error), the path cleans up and falls through to the existing need_realloc fallback, so behavior is preserved.

The grow path is guarded by the same conditions as the shrink path (no huge pages, no special vm_flags, GFP allows IO and FS), plus VM_MAP_PUT_PAGES since growing would mix allocator-supplied pages with caller-supplied ones, and a VA-range check to ensure the new size fits within the existing allocation.

The mapping prot is stored in vm_struct at allocation time and reused in the grow path, rather than hardcoding PAGE_KERNEL. This preserves the caller's prot for any allocation type, including the arch_vmap_pgprot_tagged() transformation applied under CONFIG_KASAN_HW_TAGS on arm64, where a hardcoded PAGE_KERNEL would map grown pages with MT_NORMAL instead of MT_NORMAL_TAGGED and silently disable MTE tag checks.

On __vmap_pages_range() failure, the error path calls vunmap_range() before vm_area_free_pages() to tear down any partially-installed PTEs, honoring the documented precondition of vm_area_free_pages() and mirroring the shrink path's unmap-then-free ordering.

---
 include/linux/vmalloc.h |  1 +
 mm/vmalloc.c            | 75 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 75 insertions(+), 1 deletion(-)
include/linux/vmalloc.h +1 -0
index 034a693777ca..a14472cb1858 100644
@@ -68,6 +68,7 @@ struct vm_struct {
 	phys_addr_t		phys_addr;
 	const void		*caller;
 	unsigned long		requested_size;
+	pgprot_t		prot;
 };
 
 struct vmap_area {
mm/vmalloc.c +74 -1

88 lines not on this page · raw message

---
base-commit: 68142f986ff04b2b70b31db00f719bf690f64a9a
change-id: 20260915-vmalloc_vrealloc-b51938bf3db7

Best regards,

Signature · 1 line
Ye Liu <[email protected]>