[PATCH] mm/page_alloc: Fix zone reserve update serialization

From: Muchun Song

Date: Mon May 11 2026 - 08:10:57 EST


Serialize lowmem reserve and watermark updates with the same lock so
calculate_totalreserve_pages() cannot observe partially updated zone
reserve state.

Fixes: 9726891fe753 ("mm: page_alloc: fix missed updates of lowmem_reserve in adjust_managed_page_count")
Signed-off-by: Muchun Song <songmuchun@xxxxxxxxxxxxx>
---
mm/page_alloc.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3a56825a7fc5..0989067da588 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6384,6 +6384,8 @@ static void calculate_totalreserve_pages(void)
trace_mm_calculate_totalreserve_pages(totalreserve_pages);
}

+static DEFINE_SPINLOCK(zone_reserve_lock);
+
/*
* setup_per_zone_lowmem_reserve - called whenever
* sysctl_lowmem_reserve_ratio changes. Ensures that each zone
@@ -6394,6 +6396,8 @@ static void setup_per_zone_lowmem_reserve(void)
{
struct pglist_data *pgdat;
enum zone_type i, j;
+
+ guard(spinlock_irqsave)(&zone_reserve_lock);
/*
* For a given zone node_zones[i], lowmem_reserve[j] (j > i)
* represents how many pages in zone i must effectively be kept
@@ -6509,11 +6513,9 @@ static void __setup_per_zone_wmarks(void)
void setup_per_zone_wmarks(void)
{
struct zone *zone;
- static DEFINE_SPINLOCK(lock);

- spin_lock(&lock);
- __setup_per_zone_wmarks();
- spin_unlock(&lock);
+ scoped_guard(spinlock_irqsave, &zone_reserve_lock)
+ __setup_per_zone_wmarks();

/*
* The watermark size have changed so update the pcpu batch

base-commit: e98d21c170b01ddef366f023bbfcf6b31509fa83
--
2.54.0