From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C86503E7177 for ; Tue, 17 Mar 2026 14:45:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773758750; cv=none; b=CnUocgKo7VFXE2WmmMGKVIBG/cM9ftLloFBQiJ+iJkdhs1tmvdQ1nB7spozQsqtx7IiDyfskSTgzgrPGqopnq5ow282PMjc891G7PqqYlvQzKtWUAdzUwra1FHq9xdT78210lnAueHeXa9OYBdyDxuMGoyzbDr81RoGKjSK982E= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773758750; c=relaxed/simple; bh=vWWXSXsJOObdgoBPa0ZCzYH49f6ax9/VVCivy/CV+jQ=; h=Mime-Version:Content-Type:Date:Message-Id:Subject:Cc:To:From: References:In-Reply-To; b=JE52R9byg8ExMTOSmIipc2408p8gSb+Nhk/JXoAHae39VedFOmPPG5N9XzYQiFmpTdFvtMUAOTkIEGz0WRcTsSko+id2e9KTqLd+/XOfRusyXL6PTJbdiJAniyBW545fM+cTDTikFKMpef1bAsu0N2oeHaLB5yUjVS5AGLNmnME= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rYAOlfU1; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rYAOlfU1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6F0CEC4CEF7; Tue, 17 Mar 2026 14:45:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773758750; bh=vWWXSXsJOObdgoBPa0ZCzYH49f6ax9/VVCivy/CV+jQ=; h=Date:Subject:Cc:To:From:References:In-Reply-To:From; b=rYAOlfU1LhAd33yPEOu0WvE7C2l35cFvPVoYDzFyFoaaxRtVtZOoT1IFgxIQuXo1Y 3hha8ywax6Q0nTV3aqfco4vLdEh6KFpEWP38aJmMY6FeeAVEcV36s/o5CrpW9EYgK2 FP8teTaUv3yhkB0T0IZ/4uSAoBBk7QDUhoSK0l573zFH1SJYfL5mh9nqT5Z7MeqZSV hVfvZjsxmBzPHCj6/0EO2CKlAxGIb7JcCToDeK/GNlRhQGksUEZJBGI5IY330BSbTc ahedwupp5RwGF6SOZIeJaxd9MM832F7ip2hAeygK2S4Jq3qko+vfxmV4Te9VHZu50T gPorz5mqji+7Q== Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Tue, 17 Mar 2026 15:45:48 +0100 Message-Id: Subject: Re: [PATCH v5 2/3] mm/vmalloc: free unused pages on vrealloc() shrink Cc: "Andrew Morton" , "Uladzislau Rezki" , , To: "Shivam Kalra" , "Alice Ryhl" From: "Danilo Krummrich" References: <20260317-vmalloc-shrink-v5-0-bbfbf54c5265@zohomail.in> <20260317-vmalloc-shrink-v5-2-bbfbf54c5265@zohomail.in> In-Reply-To: On Tue Mar 17, 2026 at 3:39 PM CET, Alice Ryhl wrote: > 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. >>=20 >> 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(). >>=20 >> The virtual address reservation (vm->size / vmap_area) is intentionally >> kept unchanged, preserving the address for potential future grow-in-plac= e >> support. >>=20 >> 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. >>=20 >> Signed-off-by: Shivam Kalra Feel free to add Suggested-by: Danilo Krummrich >> --- >> mm/vmalloc.c | 20 +++++++++++++++----- >> 1 file changed, 15 insertions(+), 5 deletions(-) >>=20 >> 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; >> } >> =20 >> - /* >> - * 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 <=3D old_size) { >> + unsigned int new_nr_pages =3D 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 =3D (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 =3D new_nr_pages; >> + } >> vm->requested_size =3D size; >> kasan_vrealloc(p, old_size, size); >> return (void *)p; >> @@ -4361,7 +4371,7 @@ void *vrealloc_node_align_noprof(const void *p, si= ze_t size, unsigned long align >> /* >> * We already have the bytes available in the allocation; use them. >> */ >> - if (size <=3D alloced_size) { >> + if (size <=3D (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) =3D=3D vm->nr_pages << PAGE_SHIFT, so th= ese > 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. This may well be possible. I remember that when I added vrealloc() and look= ed into growing and shrinking, I concluded that it might need a bit of rework = in terms of tracking the sizes of the different layers. Unfortunately, I don't remember the details anymore, but I'm quite sure there were some subtleties along the lines of what Alice points out, so I recommend to double check.