From: "Gregory Price (Meta)" <gourry@gourry.net>
To: linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
linux-rt-devel@lists.linux.dev, kernel-team@meta.com,
akpm@linux-foundation.org, mhocko@suse.com, rientjes@google.com,
shakeel.butt@linux.dev, rostedt@goodmis.org, mhiramat@kernel.org,
mathieu.desnoyers@efficios.com, muchun.song@linux.dev,
osalvador@suse.de, david@kernel.org, ljs@kernel.org,
liam@infradead.org, vbabka@kernel.org, rppt@kernel.org,
surenb@google.com, brendan.jackman@linux.dev, hannes@cmpxchg.org,
ziy@nvidia.com, bigeasy@linutronix.de, clrkwllms@kernel.org,
mgorman@techsingularity.net, anshuman.khandual@arm.com,
Bessel.Wang@huawei.com, jiang.liu@huawei.com,
stable@vger.kernel.org
Subject: [PATCH v3 7/8] mm/page_alloc: retry alloc_contig_pages() when the zonelist is rebuilt
Date: Tue, 20 Oct 2026 22:39:39 -0400 [thread overview]
Message-ID: <20261021023940.1940971-8-gourry@gourry.net> (raw)
In-Reply-To: <20261021023940.1940971-1-gourry@gourry.net>
Onlining the first block of a zone rebuilds every zonelist in place,
shifting the slots after the new zone. alloc_contig_pages() can then
take a range from a zone or node its filters rejected.
Writing 1 to a node's 1G nr_hugepages while that node's first
ZONE_MOVABLE block comes online puts the gigantic page in ZONE_MOVABLE,
which commit 79b63f12abcb ("mm, hugetlb: do not allocate non-migrateable
gigantic pages from movable zones") excludes.
alloc_contig_frozen_pages_noprof() walks the zonelist with the caller's
gfp and nodemask, and the iterator approves a slot before the walk loads
the zone from it:
CPU 0 CPU 1
alloc_contig_frozen_pages_noprof(GFP_HIGHUSER | __GFP_THISNODE)
slot 0 (NORMAL1) approved
online_pages()
build_all_zonelists()
[NORMAL1]
-> [MOVABLE1, NORMAL1]
zone = zonelist_zone(slot 0) /* MOVABLE1 */
alloc_contig_frozen_range(MOVABLE1 pfns)
Check zonelist_update_seq before using each zone the walk returns, and
on the way out with nothing found, and restart the walk if it changed,
as the hugetlb pool walk does.
With kprobes holding the walk across the online, the base kernel put the
1G page in ZONE_MOVABLE in 3 of 3 runs, and this change put it in
ZONE_NORMAL in 3 of 3.
Calling alloc_contig_pages() directly, GFP_KERNEL with nodemask {1} got
a ZONE_MOVABLE range and nodemask {2} a node 1 range in 3 of 3 runs
each, and neither did with this change.
Fixes: 5e27a2df03b8 ("mm/page_alloc: add alloc_contig_pages()")
Cc: stable@vger.kernel.org
Signed-off-by: Gregory Price (Meta) <gourry@gourry.net>
---
mm/page_alloc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5ca8e57c5fcbf..96ae09c8099be 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -7592,6 +7592,7 @@ struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages,
gfp_t gfp_mask, int nid, nodemask_t *nodemask)
{
unsigned long ret, pfn, flags;
+ unsigned int zonelist_cookie;
struct zonelist *zonelist;
struct zone *zone;
struct zoneref *z;
@@ -7600,8 +7601,13 @@ struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages,
retry:
zonelist = node_zonelist(nid, gfp_mask);
+ zonelist_cookie = zonelist_iter_begin();
for_each_zone_zonelist_nodemask(zone, z, zonelist,
gfp_zone(gfp_mask), nodemask) {
+ /* A rebuild may have shifted an ineligible zone into this slot. */
+ if (unlikely(check_retry_zonelist(zonelist_cookie)))
+ goto retry;
+
spin_lock_irqsave(&zone->lock, flags);
pfn = ALIGN(zone->zone_start_pfn, nr_pages);
@@ -7640,6 +7646,8 @@ struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages,
skip_hugetlb = false;
goto retry;
}
+ if (unlikely(check_retry_zonelist(zonelist_cookie)))
+ goto retry;
return NULL;
}
EXPORT_SYMBOL(alloc_contig_frozen_pages_noprof);
--
2.53.0-Meta
next prev parent reply other threads:[~2026-10-21 2:39 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 2:39 [PATCH v3 0/8] mm: fix allocator races with memory hotplug Gregory Price (Meta)
2026-10-21 2:39 ` [PATCH v3 1/8] mm/page_alloc: detect zonelist rebuilds from memory hot-add Gregory Price (Meta)
2026-10-21 2:39 ` [PATCH v3 2/8] mm/page_alloc: snapshot the preferred zone against shrink rebuilds Gregory Price (Meta)
2026-10-21 2:39 ` [PATCH v3 3/8] mm/mmzone: read each zoneref slot once when filtering by nodemask Gregory Price (Meta)
2026-10-21 2:39 ` [PATCH v3 4/8] mm/page_alloc: pass the zone, not the zoneref, to reclaim_retry_zone Gregory Price (Meta)
2026-10-21 2:39 ` [PATCH v3 5/8] mm/page_alloc: retry allocations that raced with a zonelist rebuild Gregory Price (Meta)
2026-10-21 2:39 ` [PATCH v3 6/8] mm/hugetlb: retry the pool walk when the zonelist is rebuilt Gregory Price (Meta)
2026-10-21 2:39 ` Gregory Price (Meta) [this message]
2026-10-21 2:39 ` [PATCH v3 8/8] mm/page_alloc: keep a zone's pagesets when it goes empty Gregory Price (Meta)
2026-10-21 8:24 ` [PATCH v3 0/8] mm: fix allocator races with memory hotplug David Hildenbrand (Arm)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261021023940.1940971-8-gourry@gourry.net \
--to=gourry@gourry.net \
--cc=Bessel.Wang@huawei.com \
--cc=akpm@linux-foundation.org \
--cc=anshuman.khandual@arm.com \
--cc=bigeasy@linutronix.de \
--cc=brendan.jackman@linux.dev \
--cc=clrkwllms@kernel.org \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=jiang.liu@huawei.com \
--cc=kernel-team@meta.com \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mgorman@techsingularity.net \
--cc=mhiramat@kernel.org \
--cc=mhocko@suse.com \
--cc=muchun.song@linux.dev \
--cc=osalvador@suse.de \
--cc=rientjes@google.com \
--cc=rostedt@goodmis.org \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=stable@vger.kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox