From 52dcc33881e55189650404f833c0e6b7913d6c16 Mon Sep 17 00:00:00 2001 From: Brendan Jackman Date: Wed, 15 Jul 2026 09:03:59 +0000 Subject: [PATCH] mm/page_alloc: don't spin_trylock() when disallowed in free_one_page() __free_frozen_pages() checks can_spin_trylock() before entering into the main free_frozen_page_commit()/free_one_page() path, but before this it can get to free_one_page() via the !pcp_allowed_order() and MIGRATE_ISOLATE paths. The !pcp_allowed_order() path depends on usage by callers so might not be possible in practice. The MIGRATE_ISOLATE path probably means kernel crashes and privilege escalation if anyone ever did memory hotplug and BPF tracing on a PREEMPT_RT or !SMP build. Link: https://lore.kernel.org/20260715-alloc-nolock-fixes-v1-2-fadc49952dda@google.com Signed-off-by: Brendan Jackman Fixes: 8c57b687e833 ("mm, bpf: Introduce free_pages_nolock()") Reported-by: sashiko-bot@kernel.org Closes: https://sashiko.dev/#/patchset/20260710-spin-trylock-followup-v1-0-affb5fe5ed00%40google.com?part=2 Reviewed-by: Vlastimil Babka (SUSE) Reviewed-by: Harry Yoo (Oracle) Cc: Brendan Jackman Cc: Alexei Starovoitov Cc: Johannes Weiner Cc: Michal Hocko Cc: Sebastian Andrzej Siewior Cc: Shakeel Butt Cc: Steven Rostedt Cc: Suren Baghdasaryan Cc: Zi Yan Cc: Signed-off-by: Andrew Morton --- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b3487c00971e..891f687e622c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1559,7 +1559,7 @@ static void free_one_page(struct zone *zone, struct page *page, unsigned long flags; if (unlikely(fpi_flags & FPI_TRYLOCK)) { - if (!spin_trylock_irqsave(&zone->lock, flags)) { + if (!can_spin_trylock() || !spin_trylock_irqsave(&zone->lock, flags)) { add_page_to_zone_llist(zone, page, order); return; }