On Mon, Jun 08, 2026 at 04:38:08AM -0400, Michael S. Tsirkin wrote: > When two buddy pages merge in __free_one_page(), preserve > PG_zeroed on the merged page only if both buddies have the > flag set. Otherwise clear it. > > The merged page would inherit PG_zeroed, and a later __GFP_ZERO > allocation would skip zeroing stale data in the non-zero half. > > Signed-off-by: Michael S. Tsirkin <[email protected]> > Reviewed-by: Gregory Price <[email protected]> > Assisted-by: Claude:claude-opus-4-6 > Assisted-by: cursor-agent:GPT-5.4-xhigh > --- > include/linux/page-flags.h | 1 + > mm/page_alloc.c | 15 ++++++++++++++- > 2 files changed, 15 insertions(+), 1 deletion(-) > > diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h > index 91f8ddb1d512..9365d59ac1d6 100644 > --- a/include/linux/page-flags.h > +++ b/include/linux/page-flags.h > @@ -680,6 +680,7 @@ FOLIO_FLAG_FALSE(idle) > * uses this to skip redundant zeroing in post_alloc_hook(). > */ > __PAGEFLAG(Zeroed, zeroed, PF_NO_COMPOUND) > +CLEARPAGEFLAG(Zeroed, zeroed, PF_NO_COMPOUND) > #define __PG_ZEROED (1UL << PG_zeroed) > > /* > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > index edfc83571985..a90bca5317c1 100644 > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -941,10 +941,14 @@ static inline void __free_one_page(struct page *page, > unsigned long buddy_pfn = 0; > unsigned long combined_pfn; > struct page *buddy; > + bool buddy_zeroed; > + bool page_zeroed; > bool to_tail; > > VM_BUG_ON(!zone_is_initialized(zone)); > - VM_BUG_ON_PAGE(page->flags.f & PAGE_FLAGS_CHECK_AT_PREP, page); > + /* PG_zeroed (aliased to PG_private) is valid on free-list pages */ > + VM_BUG_ON_PAGE(page->flags.f &
NIT: We don't add new VM_BUG_ON()'s, please use VM_WARN_ON(). > + (PAGE_FLAGS_CHECK_AT_PREP & ~__PG_ZEROED), page); > > VM_BUG_ON(migratetype == -1); > VM_BUG_ON_PAGE(pfn & ((1 << order) - 1), page); > @@ -979,6 +983,8 @@ static inline void __free_one_page(struct page *page, > goto done_merging; > } > > + buddy_zeroed = PageZeroed(buddy); > + > /* > * Our buddy is free or it is CONFIG_DEBUG_PAGEALLOC guard page, > * merge with it and move up one order. > @@ -997,10 +1003,17 @@ static inline void __free_one_page(struct page *page, > change_pageblock_range(buddy, order, migratetype); > } > > + page_zeroed = PageZeroed(page); > + __ClearPageZeroed(page); > + __ClearPageZeroed(buddy); > + > combined_pfn = buddy_pfn & pfn; > page = page + (combined_pfn - pfn); > pfn = combined_pfn; > order++; > + > + if (page_zeroed && buddy_zeroed) > + __SetPageZeroed(page); > } > > done_merging: > -- > MST >

