[PATCH v5 05/12] mm/mmzone: read the zoneref slot once in zonelist_zone()
From: Gregory Price (Meta)
Date: Sat Oct 31 2026 - 22:15:56 EST
Memory hotplug rebuilds zonelists in place while allocations walk them,
so a zoneref slot can change between two loads of it.
zonelist_zone() loads the slot with a plain access. The compiler may
load it again later instead of keeping the zone it already read, so a
caller can check one zone and then use another, or the NULL terminator.
Use READ_ONCE(). Callers that take a zone from a slot and keep using
it, such as get_page_from_freelist() with ac->preferred_zoneref, need
that single load.
Fixes: 11cd8638c37f ("mm, page_alloc: remove stop_machine from build_all_zonelists")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Gregory Price (Meta) <gourry@xxxxxxxxxx>
---
include/linux/mmzone.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index ecd1ebd49756..4bc2318ac37f 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -1855,7 +1855,8 @@ extern struct zone *next_zone(struct zone *zone);
static inline struct zone *zonelist_zone(struct zoneref *zoneref)
{
- return zoneref->zone;
+ /* Memory hotplug rewrites zonelists in place. */
+ return READ_ONCE(zoneref->zone);
}
static inline int zonelist_zone_idx(const struct zoneref *zoneref)
--
2.56.0