As we deployed vm.defrag_mode=1 in Meta production, some workloads
regressed with recurring pressure spikes and swap storms (which in turn
triggered userspace OOM rules on pressure and swap utilization levels).
Tracing pinned this to non-movable requests spinning and reclaiming
unproductively when kswapd/kcompactd are overwhelmed. Direct reclaim
predominantly frees up pages in movable blocks, but those requests
cannot use that space under defrag_mode rules; and it is unlikely to
free up whole blocks incidentally for __rmqueue_claim() to work.
This series fixes it by making non-movable requests participate in
pageblock production in the allocator slowpath - meaning, they will
invoke direct reclaim and direct compaction with pageblock_order.
That requires some small-ish adjustments up front in the allocator and
the compaction code: three prep patches and the fix last.
The series has been in production against one of the affected workloads
for several weeks and restores the OOM kill rate to !defrag_mode baseline.
v1: https://lore.kernel.org/20260626182215.1107966-1-hannes@cmpxchg.org/
Changes in v2:
- Patch 3 is now Vlastimil's version of the capture_control move: the
allocator owns and arms the capture control entirely, and compaction
just aims it at the zone being compacted.
- Comments on the migration source scan restrictions in patch 2, and
spelled out "small" as <pageblock_order (Vlastimil, Zi Yan)
- Corrected the Fixes tag in patch 4 - the referenced SHA was from an
old development branch (Zi Yan)
- Clarified in the cover letter what block production means (Shakeel)
- Added review/ack tags
- Cc stable on the fix (Vlastimil)
- Rebased onto mm-stable
Based on mm-stable (2026-07-06).
include/linux/compaction.h | 3 +-
mm/compaction.c | 96 +++++++++++++++++++++++++---------------------
mm/internal.h | 10 ++++-
mm/page_alloc.c | 76 ++++++++++++++++++++++++++++++------
4 files changed, 129 insertions(+), 56 deletions(-)