Re: [PATCH v3 21/26] mm/page_alloc: implement FREETYPE_UNMAPPED allocations
"Vlastimil Babka (SUSE)" <[email protected]> Mon, 3 Aug 2026 11:18:58 +0200
| Newsgroups | org.kvack.linux-mm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 7/27/26 00:22, Brendan Jackman wrote: > Currently FREETYPE_UNMAPPED allocs will always fail because, although the > lists exist to hold them, there is no way to actually create an unmapped > page block. This commit adds one, and also the logic to map it back > again when that's needed. > > Doing this at pageblock granularity ensures that the pageblock flags can > be used to infer which freetype a page belongs to. It also provides nice > batching of TLB flushes, and also avoids creating too much unnecessary > TLB fragmentation in the physmap. > > There are some functional requirements for flipping a block: > > - Unmapping requires a TLB shootdown, meaning IRQs must be enabled. > > - Updating the pagetables might require allocating a pagetable to break > down a huge page. This would deadlock if the zone lock was held. > > This makes allocations that need to change sensitivity _somewhat_ > similar to those that need to fallback to a different migratetype. But, > the locking requirements mean that this can't just be squashed into the > existing "fallback" allocator logic, instead a new allocator path just > for this purpose is needed. > > The new path is assumed to be much cheaper than the really heavyweight > stuff like compaction and reclaim. But at present it is treated as less > desirable than the mobility-related "fallback" and "stealing" logic. > This might turn out to need revision (in particular, maybe it's a > problem that __rmqueue_steal(), which causes fragmentation, happens > before __rmqueue_direct_map()), but that should be treated as a subsequent > optimisation project. > > Adding alloc_flags to gfp_freetype() requires moving it to > mm/page_alloc.h so it can refer to ALLOC_UNMAPPED. It was already only > used in internal mm code. > > Now that unmapped pageblocks actually exist, exclude them from > migration. Migrating unmapped pages via the mermap should be possible > but that's something to be added later when needed. > > Signed-off-by: Brendan Jackman <[email protected]> Reviewed-by: Vlastimil Babka (SUSE) <[email protected]> A nit below: > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -34,6 +34,7 @@ > #include <linux/folio_batch.h> > #include <linux/memory_hotplug.h> > #include <linux/nodemask.h> > +#include <linux/set_memory.h> > #include <linux/vmstat.h> > #include <linux/fault-inject.h> > #include <linux/compaction.h> > @@ -1001,6 +1002,26 @@ static void change_pageblock_range(struct page *pageblock_page, > } > } > > +/* > + * Can pages of these two freetypes be combined into a single higher-order free > + * page? > + */ > +static inline bool can_merge_freetypes(freetype_t a, freetype_t b) > +{ > + if (freetypes_equal(a, b)) > + return true; > + > + if (!migratetype_is_mergeable(free_to_migratetype(a)) || > + !migratetype_is_mergeable(free_to_migratetype(b))) > + return false; > + > + /* > + * Mustn't "just" merge pages with different freetype flags, changing > + * those requires updating pagetables. > + */ > + return freetype_flags(a) == freetype_flags(b); > +} > + > /* > * Freeing function for a buddy system allocator. > * > @@ -1069,9 +1090,7 @@ static inline void __free_one_page(struct page *page, > buddy_ft = get_pfnblock_freetype(buddy, buddy_pfn); > buddy_mt = free_to_migratetype(buddy_ft); There's a comment above this that should probably be moved to can_merge_freetypes() as well?