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


Reply via email to