Re: [PATCH v4] mm/page_alloc: avoid direct compaction for costly __GFP_NORETRY allocations
From: Salvatore Dipietro
Date: Wed Sep 23 2026 - 05:35:37 EST
On 9/19/26 06:13, Matthew Wilcox wrote:
> This patch is still piling hack on hack. We haven't made a serious
> effort to understand what's going on, we're just adjusting flags until
> things stop sucking.
I have tested two new kernel patches on v7.3-rc1, each isolating one behaviour
(diffs at the bottom), and ran the same pgbench simple-update workload
(1024 clients / 96 threads / 1200s, 3 iterations each). Baseline is the
unpatched regressed kernel; target is ~135k, the pre-5d8edfb900d5 number.
Config Avg TPS % vs baseline
v7.3-rc1 baseline (no patch) 59,408 -
(a) post-reclaim drain step skipped 70,615 +18.9%
(b) compaction disabled only 107,210 +80.5%
(c) v4 (full non-blocking, reference) 154,835 +160.6%
We can notice that:
1. The drain_all_pages() IPI is not the driver. (a) skips the whole
post-reclaim drain step for costly __GFP_NORETRY -- that is
unreserve_highatomic_pageblock(), drain_all_pages() and the retry
together -- and the entire step is worth only ~11k of the ~96k gap.
Whatever the split between the three, the cross-CPU drain cannot
account for the bulk of it.
2. Turning compaction off is not enough. Your gfp_compaction_allowed()
one-liner (b) gets about half the gap, and it declines across
iterations (135k -> 98k -> 89k). It drops compaction for
__GFP_NORETRY at every order that can use it, __GFP_THISNODE
excepted, not only at the costly order v4 gates on; the decline is
consistent with the zone no longer being repaired. (c) only makes
the costly attempt non-blocking and leaves kswapd/kcompactd working,
and it does not show the decline.
3. We have collected metrics to understand how often the
allocator stalls and normalised to a million page writebacks (nr_written),
over the same 3 x 1200s iterations as above:
compact_ allocstall_ pgscan_
stall movable direct
v7.3-rc1 baseline 513 277 90,230
(a) post-reclaim drain skipped 912 472 129,249
(b) compaction disabled 0 778 44,737
(c) v4 (full non-blocking) 5 39 4,407
The baseline enters stall compaction ~100x more often per page written
than (c) does. (a) makes all three metrics worse. (b) removes direct
compaction entirely (0 stalls) but does not remove the work: it enters
direct reclaim 2.8x more often than the baseline (778 vs 277
allocstall_movable), and still does half the baseline's direct scanning
(44,737 vs 90,230 pgscan_direct). (c) cuts both instead -- reclaim
stalls 7x lower and direct scanning 20x lower (39 and 4,407).
That is why (b) recovers only half the gap -- the stall moves from
compaction into reclaim instead of going away.
If you agree this is the right direction, I am happy to send a v6 with
(c)'s behaviour plus the defrag_mode fix discussed in the v5 thread.
Thanks,
Salvatore
---
For reproducibility, here is the exact diff behind each measured row
above (all against v7.3-rc1).
(a) post-reclaim drain step skipped -- 70,615 tps:
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4487,7 +4487,8 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order,
* pages are pinned on the per-cpu lists or in high alloc reserves.
* Shrink them and try again
*/
- if (!page && !drained) {
+ if (!page && !drained &&
+ !(order > PAGE_ALLOC_COSTLY_ORDER && (gfp_mask & __GFP_NORETRY))) {
unreserve_highatomic_pageblock(ac, false);
drain_all_pages(NULL);
drained = true;
(b) compaction disabled only -- 107,210 tps:
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -380,7 +380,8 @@ static inline bool gfp_has_io_fs(gfp_t gfp)
*/
static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
{
- return IS_ENABLED(CONFIG_COMPACTION) && (gfp_mask & __GFP_IO);
+ return IS_ENABLED(CONFIG_COMPACTION) && (gfp_mask & __GFP_IO) &&
+ (!(gfp_mask & __GFP_NORETRY) || (gfp_mask & __GFP_THISNODE));
}
AMAZON DEVELOPMENT CENTER ITALY SRL, viale Monte Grappa 3/5, 20124 Milano, Italia, Registro delle Imprese di Milano Monza Brianza Lodi REA n. 2504859, Capitale Sociale: 10.000 EUR i.v., Cod. Fisc. e P.IVA 10100050961, Societa con Socio Unico