[PATCH 5/9] mm, page_alloc: pass zone pointer to trace_reclaim_retry_zone
From: Vlastimil Babka (SUSE)
Date: Tue Oct 27 2026 - 11:57:55 EST
From: Josef Bacik <josef@xxxxxxxxxxxxxx>
should_reclaim_retry() walks a zonelist and passes the zoneref pointer
to the reclaim_retry_zone tracepoint, which loads the zone from the
entry again to find the node.
Memory hotplug rebuilds the zonelists in place while allocations are
under way. When a zone in front of the zoneref entry has become empty,
the entries move up, and this one can be the end marker by the time the
tracepoint looks at it. zonelist_node_idx() then dereferences a NULL
zone. Short of that, the event can name another zone than the one its
numbers belong to.
Pass the zone pointer instead of the zoneref pointer.
Fixes: d379f01de095 ("oom, trace: add oom detection tracepoints")
Cc: <stable@xxxxxxxxxxxxxxx>
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
Signed-off-by: Vlastimil Babka (SUSE) <vbabka@xxxxxxxxxx>
---
include/trace/events/oom.h | 8 ++++----
mm/page_alloc.c | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h
index 9f0a5d1482c4..cbcf6fe4cc61 100644
--- a/include/trace/events/oom.h
+++ b/include/trace/events/oom.h
@@ -33,7 +33,7 @@ TRACE_EVENT(oom_score_adj_update,
TRACE_EVENT(reclaim_retry_zone,
- TP_PROTO(struct zoneref *zoneref,
+ TP_PROTO(struct zone *zone,
int order,
unsigned long reclaimable,
unsigned long available,
@@ -41,7 +41,7 @@ TRACE_EVENT(reclaim_retry_zone,
int no_progress_loops,
bool wmark_check),
- TP_ARGS(zoneref, order, reclaimable, available, min_wmark, no_progress_loops, wmark_check),
+ TP_ARGS(zone, order, reclaimable, available, min_wmark, no_progress_loops, wmark_check),
TP_STRUCT__entry(
__field( int, node)
@@ -55,8 +55,8 @@ TRACE_EVENT(reclaim_retry_zone,
),
TP_fast_assign(
- __entry->node = zonelist_node_idx(zoneref);
- __entry->zone_idx = zonelist_zone_idx(zoneref);
+ __entry->node = zone_to_nid(zone);
+ __entry->zone_idx = zone_idx(zone);
__entry->order = order;
__entry->reclaimable = reclaimable;
__entry->available = available;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 13211b8caada..8f8885165045 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4675,7 +4675,7 @@ should_reclaim_retry(gfp_t gfp_mask, unsigned order,
*/
wmark = __zone_watermark_ok(zone, order, min_wmark,
ac->highest_zoneidx, alloc_flags, available);
- trace_reclaim_retry_zone(z, order, reclaimable,
+ trace_reclaim_retry_zone(zone, order, reclaimable,
available, min_wmark, *no_progress_loops, wmark);
if (wmark) {
ret = true;
--
2.56.0