Don't unconditionally clear PG_zeroed for non-reported pages in
page_del_and_expand().  Pages freed via free_frozen_pages_zeroed
(balloon deflate) already have the flag set and should keep it
through buddy allocation, not just PCP reuse.

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 | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1183ef3e91c9..1169714406e7 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1743,7 +1743,8 @@ struct page *__pageblock_pfn_to_page(unsigned long 
start_pfn,
  * -- nyc
  */
 static inline unsigned int expand(struct zone *zone, struct page *page, int 
low,
-                                 int high, int migratetype, bool reported)
+                                 int high, int migratetype, bool reported,
+                                 bool zeroed)
 {
        unsigned int size = 1 << high;
        unsigned int nr_added = 0;
@@ -1774,6 +1775,8 @@ static inline unsigned int expand(struct zone *zone, 
struct page *page, int low,
                 */
                if (reported)
                        __SetPageReported(&page[size]);
+               if (zeroed)
+                       __SetPageZeroed(&page[size]);
        }
 
        return nr_added;
@@ -1785,10 +1788,12 @@ static __always_inline void page_del_and_expand(struct 
zone *zone,
 {
        int nr_pages = 1 << high;
        bool was_reported = page_reported(page);
+       bool was_zeroed = PageZeroed(page);
 
        __del_page_from_free_list(page, zone, high, migratetype);
 
-       nr_pages -= expand(zone, page, low, high, migratetype, was_reported);
+       nr_pages -= expand(zone, page, low, high, migratetype, was_reported,
+                          was_zeroed);
        account_freepages(zone, -nr_pages, migratetype);
 }
 
@@ -2365,11 +2370,13 @@ try_to_claim_block(struct zone *zone, struct page *page,
        /* Take ownership for orders >= pageblock_order */
        if (current_order >= pageblock_order) {
                unsigned int nr_added;
+               bool was_reported = page_reported(page);
+               bool was_zeroed = PageZeroed(page);
 
                del_page_from_free_list(page, zone, current_order, block_type);
                change_pageblock_range(page, current_order, start_type);
                nr_added = expand(zone, page, order, current_order, start_type,
-                                 false);
+                                 was_reported, was_zeroed);
                account_freepages(zone, nr_added, start_type);
                return page;
        }
-- 
MST


Reply via email to