From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 3701A2C1594 for ; Tue, 18 Aug 2026 00:55:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787014559; cv=none; b=Fl7P+FqJ88jN38QOEo+8l/COGcUZBwYSJ0iQQFBwKoedKASPSxgzskw8KqdDEAglWwdG+bWaj2A7S3ciOVLAFlwwXCxaOhunqcxB8FKweYCd/tbIMV90AWQzL4V0aKOHoh9eZAY+tV7V5BCnbPCsx1rfFBRaEhWVSB8oP6aCZCk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787014559; c=relaxed/simple; bh=70cWm908sczQgK5ewIBe5+klrKFCZRia7y8ehWgMG2c=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=PJjLH5DRhUwxCqpEKhp6KrMAfYanC1umAQCXsog0CUSUVd4FxITzd68TX4pN6QhTBARxVugErJkVnrpuZqtQmaei4qhVOssUc+8GVArsZYYkuRtp6FXgPpjqiPKFXGEl81Nkr8du1zFH0kPjmRVzYj1Ggsgrh457Wh6wwpHSt7s= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BAnFOCrs; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BAnFOCrs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 02C6D1F000E9; Tue, 18 Aug 2026 00:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787014555; bh=822anQ6V2pFJxV3J/pyPbt95JgcT2z7Mv+mmnIRM7r8=; h=Date:From:To:Cc:Subject:References:In-Reply-To; b=BAnFOCrsGbiqPxHNFDh7Jz+59C0+i4VzYx81GlGcvUPCXQA147o1RyrY6zkHm3gZo aOzZXDwQTvpT/rUMI3rclVQ2hC/JkKRE3mvai2Yah9wEl1YR3JBWp4GCp5mfloGBPQ sbCliKRfy//ez30QQY2/TWKmP7MX9pH+39oUQMxIIsoLjuni7Y3tIk1jHUTg/f4xOO alW+BOe54vyfNArwWgE7JIankDSzbso4yXZrzv2VO3bs4JdKdlUg9SM43aoFaXIjwK 4hzrwpsP5yRdtp83CQWr5sgfgdjwkkG1vcfIKIpPxqwKDsCZLQ5VDDdZJ/u1G751WG d2T8EALaKBTuQ== Date: Tue, 18 Aug 2026 00:55:53 +0000 From: Yosry Ahmed To: Brendan Jackman Cc: Borislav Petkov , Dave Hansen , Peter Zijlstra , Andrew Morton , David Hildenbrand , Vlastimil Babka , Mike Rapoport , Wei Xu , Johannes Weiner , Zi Yan , Lorenzo Stoakes , linux-mm@kvack.org, linux-kernel@vger.kernel.org, x86@kernel.org, Sumit Garg , Will Deacon , rientjes@google.com, patrick.roy@linux.dev, "Itazuri, Takahiro" , Andy Lutomirski , David Kaplan , Thomas Gleixner , Patrick Bellasi , Reiji Watanabe , Sean Christopherson Subject: Re: [PATCH v3 21/26] mm/page_alloc: implement FREETYPE_UNMAPPED allocations Message-ID: References: <20260726-page_alloc-unmapped-v3-0-6f5729aa9832@google.com> <20260726-page_alloc-unmapped-v3-21-6f5729aa9832@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: On Sat, Aug 15, 2026 at 03:28:26PM +0100, Brendan Jackman wrote: > On Wed Aug 5, 2026 at 12:53 AM BST, Yosry Ahmed wrote: > >> @@ -3400,6 +3426,127 @@ static inline void zone_statistics(struct zone *preferred_zone, struct zone *z, > >> #endif > >> } > >> > >> +#ifdef CONFIG_PAGE_ALLOC_UNMAPPED > >> +/* Try to allocate a page by mapping/unmapping a block from the direct map. */ > >> +static inline struct page * > >> +__rmqueue_direct_map(struct zone *zone, unsigned int request_order, > >> + unsigned int alloc_flags, freetype_t freetype) > >> +{ > >> + unsigned int ft_flags_other = freetype_flags(freetype) ^ FREETYPE_UNMAPPED; > >> + freetype_t ft_other = migrate_to_freetype(free_to_migratetype(freetype), > >> + ft_flags_other); > >> + bool want_mapped = !(freetype_flags(freetype) & FREETYPE_UNMAPPED); > >> + enum rmqueue_mode rmqm = RMQUEUE_NORMAL; > >> + unsigned long irq_flags; > >> + int nr_pageblocks, nr_freed; > >> + struct page *page; > >> + int alloc_order; > >> + int err; > >> + > >> + if (freetype_idx(ft_other) < 0) > >> + return NULL; > >> + > >> + /* > >> + * Might need a TLB shootdown. Even if IRQs are on this isn't > >> + * safe if the caller holds a lock (in case the other CPUs need that > >> + * lock to handle the shootdown IPI). > >> + */ > >> + if (alloc_flags & ALLOC_NOBLOCK) > >> + return NULL; > >> + > >> + if (!can_set_direct_map() || alloc_flags & ALLOC_NOLOCK) > >> + return NULL; > >> + > >> + lockdep_assert(!irqs_disabled() || unlikely(early_boot_irqs_disabled)); > >> + > >> + /* > >> + * Need to [un]map a whole pageblock (otherwise it might require > >> + * allocating pagetables). First allocate it. > >> + */ > >> + alloc_order = max(request_order, pageblock_order); > >> + nr_pageblocks = 1 << (alloc_order - pageblock_order); > >> + spin_lock_irqsave(&zone->lock, irq_flags); > >> + /* First try a block that already has the right migratetype. */ > >> + page = __rmqueue(zone, alloc_order, ft_other, alloc_flags, &rmqm); > >> + if (!page) { > >> + /* Fallback to changing a block's migratetype. */ > >> + rmqm = RMQUEUE_CLAIM; > >> + page = __rmqueue(zone, alloc_order, ft_other, alloc_flags, &rmqm); > >> + } > >> + spin_unlock_irqrestore(&zone->lock, irq_flags); > >> + if (!page) > >> + return NULL; > > > > IIUC we only try to change an entire pageblock here, but what if we > > can't? If memory is fragmented enough that many pageblocks have few > > unmapped pages in them, how do we serve a mapped allocation (e.g. a slab > > allocation)? > > > > We'll go into reclaim/compaction, but there's a chance we'll end up with > > unexpected allocation failures or OOM kills even though we have free > > memory, because unmapped memory is not movable or reclaimable (as of > > now, at least). > > > > The same could happen if many pageblocks have few mapped but unmovable > > pages in them, and we make an unmapped allocation. > > Yeah, although just to be clear: those unmovable/unreclaimable pages > are _already_ un{mov,reclaim}able, ALLOC_UNMAPPED doesn't change that. > So in the situation where they prevent compaction, we were already > somewhat in trouble re memory pressure. It's just that, with > ALLOC_UNMAPPED, the allocation failures can start hitting us for > lower-order allocations whereas before they only mattered for > higher-order ones. I think that's actually a big deal. Especially for kernel allocations. For example, allocation failures in the reclaim path can be pretty detrimintal. Higher-order alloactions are usually expected to fail in some cases, but order-0 allocations, especially from the kernel, are assumed to almost always succeed. > > How much worse is that? I'm not sure - my understanding from working > with GCE people was that if fragmentation prevents allocating hugetlb > pages for guest memory, yes in theory the system can fall back to base > pages, but in practice the perf hit from doing that is intolerable, i.e. > successful higher-order allocations are basically a hard requirement in > the real world already. Is that unique to GCE or are other workloads > like that too? I don't really know :/ > > The OTHER thing, trying to see this as zoomed-out as possible, is that > the "unmapped pages are un{mov,reclaim}able" thing is hopefully very > temporary? I'm pretty sure we want at least compaction for guest_memfd > [0]. If we extend ALLOC_UNMAPPED into any other areas I also expect that > to be the same. Secretmem is... well, whatever. So I think the "real" > fix is to support compaction. We'll still always have unmovable or unreclaimable pages. Even with ASI, some userspace memory may be pinned or mlocked. The fact that some memory can simply be un-allocatable by the kernel is.. scary, especially without watermark awareness (see my other response to patch 24). > > [0]: https://lore.kernel.org/all/20260805-shivank-gmem-migrate-v3-9-00d8bdec4e1d@amd.com/ > > > I wonder if we still need a fallback case where a pageblock contains a > > mix of mapped and unmapped pages. We need to carefully handle such > > pageblocks: > > - For unmapped allocations, we need to unmap the relevant PTEs and > > potentially do a TLB shootdown (if they were previously mapped). Maybe > > we should always flush the TLB for simplicity for now. > > - For mapped allocations, we need to map the relevant PTEs. No TLB > > shootdown should be needed. > > > > Assuming unmapped allocations are always zeroed by the users on alloc > > and free, we don't need to worry about zeroing pages either way. > > > > We may want to track the number of unmapped pages in such page blocks to > > now when it's fully mapped or fully unmapped and change its type, but > > maybe this can be a followup if needed. > > ... However, yes this might be unavoidable despite what I said above. > This was also DavidH's feeling when I chatted to him a few months back. > The hard parts of it are a) the tracking as you hinted at and b) in the > general case that means allocating pagetables. I am considering a simple-ish scheme to avoid per-page tracking and potential TLB shootdowns in the freeing path (which prompted async freeing internally). What if we just always map pages in such tainted/mixed pageblocks when they are freed? If they are already mapped, nothing to do. If unmapped, we map them and zero them. No TLB shootdown required. We also shouldn't ever need to allocate. If the pages were previously unmapped, we should have already allocated any necessary page tables. Right? Zeroing on free may still be bad, but not prohibitive, and hopefully this is only a fallback. We'll need to figure out where this fallback fits (e.g. before or after reclaim/compaction). > > So yeah I think it's probably doable but I _really_ want to avoid doing > it in this series if we possibly can. Yeah I am trying to figure out whether the issue is theoretical enough that we can do it in a follow up.