Add a _user variant of alloc_contig_frozen_pages that accepts a user_addr parameter for cache-friendly zeroing of contiguous allocations.
No functional change; all existing callers continue to pass USER_ADDR_NONE. Signed-off-by: Michael S. Tsirkin <[email protected]> Assisted-by: Claude:claude-opus-4-6 --- include/linux/gfp.h | 6 ++++++ mm/page_alloc.c | 32 +++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index ee35c5367abc..73109d4e31a4 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -453,6 +453,12 @@ struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages, #define alloc_contig_frozen_pages(...) \ alloc_hooks(alloc_contig_frozen_pages_noprof(__VA_ARGS__)) +struct page *alloc_contig_frozen_pages_user_noprof(unsigned long nr_pages, + gfp_t gfp_mask, int nid, nodemask_t *nodemask, + unsigned long user_addr); +#define alloc_contig_frozen_pages_user(...) \ + alloc_hooks(alloc_contig_frozen_pages_user_noprof(__VA_ARGS__)) + struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask, int nid, nodemask_t *nodemask); #define alloc_contig_pages(...) \ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b96c9892f6c6..b725a3b59835 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -6999,8 +6999,9 @@ static void __free_contig_frozen_range(unsigned long pfn, unsigned long nr_pages * * Return: zero on success or negative error code. */ -int alloc_contig_frozen_range_noprof(unsigned long start, unsigned long end, - acr_flags_t alloc_flags, gfp_t gfp_mask) +static int __alloc_contig_frozen_range(unsigned long start, unsigned long end, + acr_flags_t alloc_flags, gfp_t gfp_mask, + unsigned long user_addr) { const unsigned int order = ilog2(end - start); unsigned long outer_start, outer_end; @@ -7127,7 +7128,7 @@ int alloc_contig_frozen_range_noprof(unsigned long start, unsigned long end, struct page *head = pfn_to_page(start); check_new_pages(head, order); - prep_new_page(head, order, gfp_mask, 0, USER_ADDR_NONE); + prep_new_page(head, order, gfp_mask, 0, user_addr); } else { ret = -EINVAL; WARN(true, "PFN range: requested [%lu, %lu), allocated [%lu, %lu)\n", @@ -7137,6 +7138,13 @@ int alloc_contig_frozen_range_noprof(unsigned long start, unsigned long end, undo_isolate_page_range(start, end); return ret; } + +int alloc_contig_frozen_range_noprof(unsigned long start, unsigned long end, + acr_flags_t alloc_flags, gfp_t gfp_mask) +{ + return __alloc_contig_frozen_range(start, end, alloc_flags, gfp_mask, + USER_ADDR_NONE); +} EXPORT_SYMBOL(alloc_contig_frozen_range_noprof); /** @@ -7255,8 +7263,9 @@ static bool zone_spans_last_pfn(const struct zone *zone, * * Return: pointer to contiguous frozen pages on success, or NULL if not successful. */ -struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages, - gfp_t gfp_mask, int nid, nodemask_t *nodemask) +struct page *alloc_contig_frozen_pages_user_noprof(unsigned long nr_pages, + gfp_t gfp_mask, int nid, nodemask_t *nodemask, + unsigned long user_addr) { unsigned long ret, pfn, flags; struct zonelist *zonelist; @@ -7284,10 +7293,11 @@ struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages, * win the race and cause allocation to fail. */ spin_unlock_irqrestore(&zone->lock, flags); - ret = alloc_contig_frozen_range_noprof(pfn, + ret = __alloc_contig_frozen_range(pfn, pfn + nr_pages, ACR_FLAGS_NONE, - gfp_mask); + gfp_mask, + user_addr); if (!ret) return pfn_to_page(pfn); spin_lock_irqsave(&zone->lock, flags); @@ -7309,6 +7319,14 @@ struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages, } return NULL; } +EXPORT_SYMBOL(alloc_contig_frozen_pages_user_noprof); + +struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages, + gfp_t gfp_mask, int nid, nodemask_t *nodemask) +{ + return alloc_contig_frozen_pages_user_noprof(nr_pages, gfp_mask, nid, + nodemask, USER_ADDR_NONE); +} EXPORT_SYMBOL(alloc_contig_frozen_pages_noprof); /** -- MST

