[RFC PATCH v4 0/4] mm: avoid large folio splits when swap is unavailable
Xueyuan Chen <[email protected]> Thu, 30 Jul 2026 10:16:26 +0800
| Newsgroups | org.kernel.vger.cgroups,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
This is RFC v4 of Barry's original RFC patch, "mm: Avoiding split large folios if swap has no space": https://lore.kernel.org/r/[email protected] Barry's RFC showed the no-swap case with MADV_PAGEOUT on 16KB mTHP: the large-folio split counter increased by 1024 even though no swapout progress was possible. Skipping the split in that case kept the counter at 0. This version keeps that behavior, but makes folio_alloc_swap() classify the failure. The function sees both the swap allocation result and the memcg swap charge result, so callers only split when a smaller folio might still be swapped out. Patch #1 adds page_counter_margin(), a small helper that computes the minimum remaining chargeable space across a page_counter hierarchy. Patch #2 lets folio_alloc_swap() distinguish large-folio swap allocation failures: - -E2BIG: splitting may let smaller folios make progress - -ENOSPC: no global swap space is available - -ENOMEM: splitting is not expected to help, including memcg swap charge failures with no remaining swap capacity Patch #3 makes vmscan split a large folio only when folio_alloc_swap() returns -E2BIG. Other failures keep the existing activation path and avoid destroying the large folio when no smaller part can be backed by swap either. Patch #4 applies the same contract to shmem_writeout(), which previously split a large folio on every folio_alloc_swap() failure. It now enters the split fallback only on -E2BIG; other failures redirty and reactivate the folio as before. RFC v3 -> RFC v4: - Keep global swap availability and memcg swap margin separate, following feedback from Barry Song, Johannes Weiner, and Youngjun Park. - Handle early rejections and memcg charge failures with the refined folio_alloc_swap() return-value contract. - Apply the requested vmscan and shmem condition layout changes. - https://lore.kernel.org/r/[email protected] RFC v2 -> RFC v3: - Use Johannes Weiner's original page_counter_margin() patch and preserve his authorship. Move the mem_cgroup_get_nr_swap_pages() conversion into Patch #1 so the helper addition remains a pure refactoring. - Add Patch #4 to make shmem_writeout() split large folios only on -E2BIG, as suggested by Baolin Wang. - https://lore.kernel.org/r/[email protected] RFC v1 -> RFC v2: - Split the RFC into helper, swap allocation, and vmscan patches. - Add page_counter_margin() and use it for hierarchical memcg swap capacity checks. - Make folio_alloc_swap() return -E2BIG only when a smaller folio may still be swapped out. - Return -ENOSPC for no global swap space and -ENOMEM when splitting is not expected to help, including memcg swap exhaustion. - Make vmscan split large folios only on -E2BIG from folio_alloc_swap(). Testing: - make -j16 W=1 mm/page_counter.o mm/memcontrol.o mm/swapfile.o mm/vmscan.o mm/shmem.o - scripts/checkpatch.pl --strict --git akpm/mm-unstable..HEAD - git diff --check akpm/mm-unstable..HEAD - scripts/kernel-doc -none mm/page_counter.c mm/memcontrol.c mm/swapfile.c - Apply-check the exported series against akpm/mm-unstable Runtime testing is pending. Barry Song (Xiaomi) (1): mm/vmscan: avoid pointless large folio splits without swap Johannes Weiner (1): mm: add page_counter_margin() Xueyuan Chen (2): mm: distinguish large folio swap allocation failures mm/shmem: split large folios only on -E2BIG include/linux/page_counter.h | 1 + include/linux/swap.h | 16 ++++++++++---- mm/memcontrol.c | 41 +++++++++++++++++++++++++++++------ mm/page_counter.c | 20 ++++++++++++++++++ mm/shmem.c | 6 ++++-- mm/swapfile.c | 32 +++++++++++++++++++++------- mm/vmscan.c | 7 +++++- 7 files changed, 101 insertions(+), 22 deletions(-) base-commit: c73b725a57f276a3702ca213bde78fca029bc619 -- 2.47.3