Re: [PATCH 2/9] mm/page_alloc: Add a bulk page allocator
From: Mel Gorman <hidden>
Date: 2021-04-12 10:59:46
Also in:
linux-mm, linux-nfs, lkml
On Mon, Apr 12, 2021 at 12:21:42PM +0200, Vlastimil Babka wrote:
quoted
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8a3e13277e22..eb547470a7e4 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c@@ -4965,6 +4965,124 @@ static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order, return true; } +/* + * __alloc_pages_bulk - Allocate a number of order-0 pages to a list + * @gfp: GFP flags for the allocation + * @preferred_nid: The preferred NUMA node ID to allocate from + * @nodemask: Set of nodes to allocate from, may be NULL + * @nr_pages: The number of pages desired on the list + * @page_list: List to store the allocated pages + * + * This is a batched version of the page allocator that attempts to + * allocate nr_pages quickly and add them to a list. + * + * Returns the number of pages on the list. + */ +int __alloc_pages_bulk(gfp_t gfp, int preferred_nid, + nodemask_t *nodemask, int nr_pages, + struct list_head *page_list) +{ + struct page *page; + unsigned long flags; + struct zone *zone; + struct zoneref *z; + struct per_cpu_pages *pcp; + struct list_head *pcp_list; + struct alloc_context ac; + gfp_t alloc_gfp; + unsigned int alloc_flags;Was going to complain that this is not set to ALLOC_WMARK_LOW. Must be faster next time...
Good that you caught it anyway!
quoted
+ int allocated = 0; + + if (WARN_ON_ONCE(nr_pages <= 0)) + return 0; + + /* Use the single page allocator for one page. */ + if (nr_pages == 1) + goto failed; + + /* May set ALLOC_NOFRAGMENT, fragmentation will return 1 page. */I don't understand this comment. Only alloc_flags_nofragment() sets this flag and we don't use it here?
It's there as a reminder that there are non-obvious consequences to ALLOC_NOFRAGMENT that may affect the bulk allocation success rate. __rmqueue_fallback will only select pageblock_order pages and if that fails, we fall into the slow path that allocates a single page. I didn't deal with it because it was not obvious that it's even relevant but I bet in 6 months time, I'll forget that ALLOC_NOFRAGMENT may affect success rates without the comment. I'm waiting for a bug that can trivially trigger a case with a meaningful workload where the success rate is poor enough to affect latency before adding complexity. Ideally by then, the allocation paths would be unified a bit better.
quoted
+ gfp &= gfp_allowed_mask; + alloc_gfp = gfp; + if (!prepare_alloc_pages(gfp, 0, preferred_nid, nodemask, &ac, &alloc_gfp, &alloc_flags)) + return 0; + gfp = alloc_gfp; + + /* Find an allowed local zone that meets the high watermark. */Should it say "low watermark"?
Yeah, that's leftover from an earlier prototype :( -- Mel Gorman SUSE Labs