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.

Without this, a zeroed page (freed via free_frozen_pages_zeroed
from balloon deflate) could merge with a non-zero buddy.  The merged
page would inherit PG_zeroed, and a later __GFP_ZERO allocation
would skip zeroing stale data in the non-zero half.

The page reporting path is not affected: it sets PG_zeroed during
allocation (page_del_and_expand), not on free list pages.

Signed-off-by: Michael S. Tsirkin <[email protected]>
Assisted-by: Claude:claude-opus-4-6
Assisted-by: cursor-agent:GPT-5.4-xhigh
---
 mm/page_alloc.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 9311374bbd2d..122b49a6d435 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -991,6 +991,8 @@ 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));
@@ -1029,6 +1031,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.
@@ -1047,10 +1051,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


Reply via email to