From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9486E3E3C6A for ; Tue, 17 Mar 2026 14:39:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773758348; cv=none; b=dY02hylvCPRg9zDAOqhO25rcvikuG9uDqwUpfrmyrH1LhTkdXayKVPtQDJQmuIlrq25fFCOq9LbfdQlih8HQ4oUoGTZ/N8cTjCLLxXPr0FFZ67wkUeHJsm/s7qXrpONe3Ia3YqZqpt/2HdlBq11zz+Hbr7bb8egFhR16y7LRmr8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773758348; c=relaxed/simple; bh=fkhZG9t2xZjVMZFCeWXNVZ6PtRqENX+XoLXt4AxeQp4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=tI0y5Vu1d67K7oYqrYzBsamBx18n8BVMapMYAI6Dltn2A3EfxtLB1aGWcWKTyhXZmbRtBFZEYmaqcdOM86zW2eTRdT0WEgSG8+uX2fyC4M9fKeNygLsU11xCkQsgq8WORIgpxhzhIzaGojPZjS8cQPQ67mwqzCwzJlbkPxG0YrA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=iftnXjL/; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="iftnXjL/" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-4853466655dso54621175e9.3 for ; Tue, 17 Mar 2026 07:39:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1773758345; x=1774363145; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ReWBU8Bc/S6OUN3h3h2h1ud20QtQ0sSv8RvGJ9uBmaI=; b=iftnXjL/KcpoIcRKKBL8q+DxVp4/yUb4xocSZYqKERAeovoVPuhK3zKQS/39pbm2Tt aNqJd4MFCqFyYNaTG/HsT6MRA/j0bqLaWp43sokYlqkMUznHQr8N9cBZyCDW2rqZDxXI ssStDWBbDzuxggaH2DnDboFKsNSr1OeDXMDKQV1X7UdlNDy34PxqM8i57YitvZDFMBdb EVvy+C3mgFN6YUap/8afuCruNik/PKlkRXbYNgsMjRvmom8389mS/Q/1B+sK2zP3eDhl l4/f1TE5vFeVP0JThvZ6TtTVv4Im6u098JfG4zSMlk0MqCI+DDzmSe+ZPd4Gq3iilJxi fYXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773758345; x=1774363145; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ReWBU8Bc/S6OUN3h3h2h1ud20QtQ0sSv8RvGJ9uBmaI=; b=RnVAH8Mg+0lxPg1uK8Ljaf0Al2njZW0uSTAguNSw+k8pz7Kh4N8SFVVr573AJFrWgc VqnP+J3qRu0n2GjnPJwOwjvUIl0O3b2+R1NATnmvMQa/L9Iv9Jjt4edfv2mZ8vzmZmoT IflEmlnRqy9YY+mLC5Zs44sTeD4X0VspcjlT4JeOxKZhhvOJrKzEuk5TwSlrecezcTr/ bK5bbvT2cHs5tv5CKbBzGNUTmyKVokWPIWz/T95HRAorlIYYihgSBZrQNKb9skcRiue4 Ax7DKnbfHBExtexwllIUohEnflY4oIm+YNRdSWoZ7yaLGQZ2Y/QpWI7xJggUMad8hwyg TKxw== X-Forwarded-Encrypted: i=1; AJvYcCXRy2fzGVtUUUSFuVqOSatexEcm6R4L1k1R1kVlO8nw7ewLa8PGFdh/S4hubN918Gt61zL0sJ9dAYoqXNo=@vger.kernel.org X-Gm-Message-State: AOJu0YyL3N231FWTg+15gutGQDJfoJZOogBzWxMgkiqLBWk0OgxPmEJI 1d3SrYZMcKuA50F18tEE4LUH5EnCTvFNcqBKG9yUBYb6gqMebDPuHNYb/bW/1K+UKLAQb7HPeKO 0OymWr/CPUKWopKMcqA== X-Received: from wmbgz9-n1.prod.google.com ([2002:a05:600c:8889:10b0:485:3a14:a74e]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3b16:b0:480:69b6:dfed with SMTP id 5b1f17b1804b1-4855671e83bmr294659805e9.24.1773758344794; Tue, 17 Mar 2026 07:39:04 -0700 (PDT) Date: Tue, 17 Mar 2026 14:39:01 +0000 In-Reply-To: <20260317-vmalloc-shrink-v5-2-bbfbf54c5265@zohomail.in> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260317-vmalloc-shrink-v5-0-bbfbf54c5265@zohomail.in> <20260317-vmalloc-shrink-v5-2-bbfbf54c5265@zohomail.in> Message-ID: Subject: Re: [PATCH v5 2/3] mm/vmalloc: free unused pages on vrealloc() shrink From: Alice Ryhl To: Shivam Kalra Cc: Andrew Morton , Uladzislau Rezki , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Danilo Krummrich Content-Type: text/plain; charset="utf-8" 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 > --- > 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