Re: [RFC PATCH 4/4] mm: adjust free_pages to make __zone_watermark_ok() mTHP-aware
From: Bo Zhang
Date: Thu Sep 03 2026 - 12:53:21 EST
Thanks for the review. (The "defrag_mode & order" bitwise bug was already
covered in the reply to Xueyuan Chen; it will use "&&" in v2.) Replying to
the other two points below.
1) mTHP count discarded by the percpu_drift_mark fallback
Sashiko says
"The restricted mTHP free_pages count is being compared against
zone->percpu_drift_mark, which is tuned for the total number of free pages
... won't this condition almost always evaluate to true under memory
pressure? If so, it would unconditionally overwrite free_pages with the
snapshot of NR_FREE_PAGES, bypassing the new mTHP logic entirely."
Right. percpu_drift_mark is calibrated against total free pages. Under
fragmentation or memory pressure - exactly when pgdat_balanced() matters -
the >= mTHP-order free blocks shrink relative to total free pages, so the
mTHP subset drops below percpu_drift_mark and the snapshot overwrites it,
bypassing the mTHP value. In any case the drift correction shouldn't apply
to the mTHP path: it reads free_area directly, which is already exact and
not subject to per-cpu drift.
2) Restricted subset can go negative in __zone_watermark_ok()
Sashiko says
"Since __zone_watermark_unusable_free() includes all order-0 cma and
highatomic pages across the entire zone, subtracting the global unusable
total from the heavily restricted subset can push free_pages negative. This
fails the watermark check permanently and can cause kswapd to spin
endlessly."
The operand mismatch is a pre-existing pattern, not something this patch
introduces: the existing defrag_mode path already feeds a subset
(NR_FREE_PAGES_BLOCKS, only >= pageblock_order) into __zone_watermark_ok()
the same way, and my mTHP subset (>= order-2) is actually a superset of
that, so it's larger and less likely to go negative. Going negative would
require an extreme case - near-zero free blocks of the target order plus a
non-trivial amount of free CMA/highatomic. If the existing order-9 subset
path doesn't need special handling here, the order-2 subset doesn't either,
so I don't plan to change this behavior in the series.
For point 1, the initial free_pages goes through zone_effective_free_pages()
(three paths: blocks / mTHP subset / total), but the percpu_drift snapshot
fallback only has two paths and has no mTHP case, so the mTHP subset falls
into the NR_FREE_PAGES total path and gets overwritten. In v2 I'll make the
snapshot fallback symmetric with zone_effective_free_pages() so the mTHP
path stays consistent (the mTHP count is read directly from free_area and
isn't subject to per-cpu drift anyway). Point 2 is an existing property of
the subset-based watermark check rather than something specific to this
patch. Suggestions welcome if a different overall shape is preferred.
Bo