2021-06-28 23:40:13

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH v2] mm/page_alloc: Return nr_populated when the array is full

The SUNRPC consumer of __alloc_bulk_pages() legitimately calls it
with a full array sometimes. In that case, the correct return code,
according to the API contract, is to return the number of pages
already in the array/list.

Let's clean up the return logic to make it clear that the returned
value is always the total number of pages in the array/list, not the
number of pages that were allocated during this call.

Fixes: b3b64ebd3822 ("mm/page_alloc: do bulk array bounds check after checking populated elements")
Signed-off-by: Chuck Lever <[email protected]>
---
mm/page_alloc.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ef2265f86b91..270719898b47 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5047,7 +5047,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
int nr_populated = 0;

if (unlikely(nr_pages <= 0))
- return 0;
+ goto out;

/*
* Skip populated array elements to determine if any pages need
@@ -5058,7 +5058,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,

/* Already populated array? */
if (unlikely(page_array && nr_pages - nr_populated == 0))
- return 0;
+ goto out;

/* Use the single page allocator for one page. */
if (nr_pages - nr_populated == 1)
@@ -5068,7 +5068,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
gfp &= gfp_allowed_mask;
alloc_gfp = gfp;
if (!prepare_alloc_pages(gfp, 0, preferred_nid, nodemask, &ac, &alloc_gfp, &alloc_flags))
- return 0;
+ goto out;
gfp = alloc_gfp;

/* Find an allowed local zone that meets the low watermark. */
@@ -5141,6 +5141,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,

local_irq_restore(flags);

+out:
return nr_populated;

failed_irq:
@@ -5156,7 +5157,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
nr_populated++;
}

- return nr_populated;
+ goto out;
}
EXPORT_SYMBOL_GPL(__alloc_pages_bulk);




2021-06-29 08:24:48

by Mel Gorman

[permalink] [raw]
Subject: Re: [PATCH v2] mm/page_alloc: Return nr_populated when the array is full

On Mon, Jun 28, 2021 at 02:12:59PM -0400, Chuck Lever wrote:
> The SUNRPC consumer of __alloc_bulk_pages() legitimately calls it
> with a full array sometimes. In that case, the correct return code,
> according to the API contract, is to return the number of pages
> already in the array/list.
>
> Let's clean up the return logic to make it clear that the returned
> value is always the total number of pages in the array/list, not the
> number of pages that were allocated during this call.
>
> Fixes: b3b64ebd3822 ("mm/page_alloc: do bulk array bounds check after checking populated elements")
> Signed-off-by: Chuck Lever <[email protected]>

Commit 66d9282523b3 ("mm/page_alloc: Correct return value of populated
elements if bulk array is populated") has since been merged as it was
the minimal obvious for the problem introduced but I have no objection
to your patch being rebased on top and sent as a cleanup.

Thanks.

--
Mel Gorman
SUSE Labs