On Tue, May 12, 2026 at 05:07:05PM -0400, Michael S. Tsirkin wrote:
> Propagate PG_zeroed through buddy splits in page_del_and_expand()
> and try_to_claim_block(). When a zeroed high-order page is split
> to satisfy a smaller allocation, the sub-pages placed back on the
> free lists keep PG_zeroed.
>
> 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
Already reviewed this, but noticing the same pattern - wondering if we
should just snapshot all the flags and plumb it through instead of just
extending functions like this to have infinite bools.
> ---
> mm/page_alloc.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index d70c9ba6b329..468e8bde7d34 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -1712,7 +1712,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;
> @@ -1743,6 +1744,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;
> @@ -1754,10 +1757,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);
> }
>
> @@ -2335,11 +2340,12 @@ try_to_claim_block(struct zone *zone, struct page
> *page,
> 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,
> - was_reported);
> + was_reported, was_zeroed);
> account_freepages(zone, nr_added, start_type);
> return page;
> }
> --
> MST
>