Defer the initialisation of the page refcount to the new __alloc_pages() wrapper and turn the old __alloc_pages() into __alloc_frozen_pages(). Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- mm/internal.h | 2 ++ mm/page_alloc.c | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/mm/internal.h b/mm/internal.h index 08d0881223cf..7e6079216a17 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -362,6 +362,8 @@ extern void post_alloc_hook(struct page *page, unsigned int order, gfp_t gfp_flags); extern int user_min_free_kbytes; +struct page *__alloc_frozen_pages(gfp_t, unsigned int order, int nid, + nodemask_t *); void free_frozen_pages(struct page *, unsigned int order); void free_unref_page_list(struct list_head *list); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index f1b7fc657c74..359a92113152 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5476,8 +5476,8 @@ EXPORT_SYMBOL_GPL(__alloc_pages_bulk); /* * This is the 'heart' of the zoned buddy allocator. */ -struct page *__alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid, - nodemask_t *nodemask) +struct page *__alloc_frozen_pages(gfp_t gfp, unsigned int order, + int preferred_nid, nodemask_t *nodemask) { struct page *page; unsigned int alloc_flags = ALLOC_WMARK_LOW; @@ -5533,13 +5533,22 @@ struct page *__alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid, free_frozen_pages(page, order); page = NULL; } - if (page) - set_page_refcounted(page); trace_mm_page_alloc(page, order, alloc_gfp, ac.migratetype); return page; } + +struct page *__alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid, + nodemask_t *nodemask) +{ + struct page *page; + + page = __alloc_frozen_pages(gfp, order, preferred_nid, nodemask); + if (page) + set_page_refcounted(page); + return page; +} EXPORT_SYMBOL(__alloc_pages); struct folio *__folio_alloc(gfp_t gfp, unsigned int order, int preferred_nid, -- 2.35.1