Re: [RFC PATCH 2/5] mm/page_alloc: count a merged buddy's pages under the merged type

From: Johannes Weiner

Date: Wed Oct 14 2026 - 16:40:52 EST


On Tue, Oct 06, 2026 at 10:12:47PM -0400, Rik van Riel wrote:
> __free_one_page() merges a freed page with a free buddy of another
> mergeable type at pageblock order and above, and retypes the buddy to
> match. The buddy's pages stay counted under the old type: nothing moves
> them to the merged type in the free counts.
>
> That is unobservable today. NR_FREE_PAGES does not separate types, so the
> missing move nets to zero there. Any future per-type free count would
> undercount on a merge from the other side, and allocating the merged
> run later could wrap it.
>
> Move the buddy's pages to the merged type in the count too.
>
> Assisted-by: LLM
> Signed-off-by: Rik van Riel <riel@xxxxxxxxxxx>
> ---
> mm/page_alloc.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 4658af97be010..ae38e25971559 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -993,6 +993,11 @@ static inline void __free_one_page(struct page *page,
> account_freepages(zone, 1 << order, migratetype);
> } else {
> __del_page_from_free_list(buddy, zone, order, buddy_mt);
> + /* The buddy's free pages join the merged block's type. */
> + if (unlikely(buddy_mt != migratetype)) {
> + account_freepages(zone, -(1 << order), buddy_mt);
> + account_freepages(zone, 1 << order, migratetype);

Reasonable on one hand, but I think at that point it would be simpler
and more robust to drop that 'single account_freepages() + __add/__del
operations' optimization, and just use the accounting add/del variants
directly instead.