Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 00/11] mm, swap: dynamic cluster management for xswap devices
@ 2026-07-27 13:50 Baoquan He
  2026-07-27 13:50 ` [RFC PATCH 01/11] mm: xswap support for zswap Baoquan He
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Baoquan He @ 2026-07-27 13:50 UTC (permalink / raw)
  To: linux-mm
  Cc: akpm, chrisl, nphamcs, kasong, baohua, youngjun.park, hannes,
	yosry, david, shikemeng, chengming.zhou, linux-kernel, Baoquan He

This series implements step 3 of the incremental path proposed in [1]:
a virtual swap device with dynamic cluster growth and shrink, backed
only by zswap, no writeback yet.

During the discussion in [2], Chris and Nhat debated xarray-based vs
array-based cluster lookup for virtual swap.  Chris argued for keeping
the swap table and cluster_info in the same place with O(1) array
indexing, and suggested that the kvmalloc grow approach here should
provide the cluster management VS needs.  He further proposed using
the same grow technique for the future per-slot backend pointer array
(vs_table), keeping a single coherent array layout throughout.

This series therefore serves as the foundation: once the dynamic
cluster management lands, Nhat's VS series can build the per-slot
backend pointer, writeback, and rmap on top of it — without an extra
xarray lookup in the cluster access path.

A note on naming: Nhat's series uses "virtual swap" (VS), Chris
originally used "ghost swap", and now suggests "xswap" (extendable
swap).  This series uses "xswap" as a temporary convention; the final
name is open for discussion.

xswap decouple swap slots from physical backing storage.  Currently
zswap requires a backing swap device sized for the full virtual
capacity, even when writeback is never needed — wasting disk space on
slots that zswap will never use. An xswap device is a swapfile: a 4K
on-disk header advertises the capacity, but there is no swap data
section.  This eliminates the wasted backing storage.

This series replaces the fixed allocation with a VM_SPARSE vmalloc
area that grows on demand and shrinks when clusters are freed, within
the bounds set at swapon.  The cluster_info pages are mapped lazily
via vm_area_map_pages() and unmapped in bulk when contiguous free
clusters accumulate at the tail.  Lookup is O(1) via simple array
indexing, which matters on the swapout hot path.  The trade-off is
coarser shrink granularity (full pages, not individual clusters), but
for the initial landing where swap usage tends to be ratchet-like,
this is a reasonable choice.

[1] https://lore.kernel.org/all/al8ohWshSSZ64AtT@MiWiFi-R3L-srv/
[2] https://lore.kernel.org/all/CACePvbVJGVDbhvPRNsZx-f4t16TU-t6H754JOUQQ4uF2Xe6Q5w@mail.gmail.com/

Design
======

The cluster_info[] array lives in a VM_SPARSE vm_struct.  Physical
pages are allocated and mapped into it in chunks of XSWAP_GROW_CLUSTERS
(256, configurable).  When the allocator runs out of free clusters and
the mapped range hasn't reached the ceiling, the grow path maps more
pages.  Symmetrically, when clusters are freed, a shrink path unmap
pages from the tail if enough contiguous free clusters accumulate.

To avoid scanning cluster_info[] on every shrink opportunity, a
nr_free_tail counter provides O(1) detection — it tracks how many
clusters at the tail are free.  Shrink fires when the counter reaches
the threshold.

A per-device runtime ceiling (nr_clusters) allows userspace to cap
the mapped range below the hard limit, and a debugfs knob exposes it
for live tuning without swapoff/swapon.

Testing
======
1. Create xswap swapfile
touch swap.4G
truncate -s 4G swap.4G
mkswap swap.4G
dd if=swap.4G of=ghost.4G bs=4096 count=1

2. swapon
swapon ghost.4G

3. memory pressure testing
echo 1 > /sys/module/zswap/parameters/enabled
stress-ng --vm 1 --vm-bytes 4G --vm-keep --timeout 120s

4. shrink and grow memory via debugfs knob

root@fedora:~# cat /sys/kernel/debug/xswap/type0_cluster_limit 
4096
root@fedora:~# echo 2048 > /sys/kernel/debug/xswap/type0_cluster_limit
root@fedora:~# cat /sys/kernel/debug/xswap/type0_cluster_limit 
2048

I did test cases and all passed:
swapon, swapoff
swapon, during stress-ng shrink and grow xswap size
swapon, stress-ng, then poweroff when stress-ng finished
=====

Baoquan He (10):
  mm, swap: add CONFIG_XSWAP and xswap fields to swap_info_struct
  mm, swap: add xswap cluster grow via VM_SPARSE vmalloc
  mm, swap: add xswap grow trigger on cluster allocation
  mm, swap: add xswap_try_shrink and shrink trigger on cluster free
  mm, swap: free backing pages in xswap_unmap_clusters
  mm, swap: add nr_free_tail for O(1) xswap shrink detection
  mm, swap: add adjustable runtime ceiling (nr_clusters) for xswap
  mm, swap: add debugfs knob for xswap per-device cluster limit
  mm, swap: defer xswap shrink to workqueue to avoid lock recursion
  mm, swap: serialize xswap map/unmap with a mutex

Chris Li (1):
  mm: xswap support for zswap

 include/linux/swap.h |  12 +
 mm/Kconfig           |   9 +
 mm/page_io.c         |  16 +
 mm/swap_state.c      |   7 +
 mm/swapfile.c        | 677 +++++++++++++++++++++++++++++++++++++++++--
 mm/zswap.c           |   9 +-
 6 files changed, 709 insertions(+), 21 deletions(-)

-- 
2.54.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2026-07-27 16:09 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27 13:50 [RFC PATCH 00/11] mm, swap: dynamic cluster management for xswap devices Baoquan He
2026-07-27 13:50 ` [RFC PATCH 01/11] mm: xswap support for zswap Baoquan He
2026-07-27 14:04 ` [RFC PATCH 02/11] mm, swap: add CONFIG_XSWAP and xswap fields to swap_info_struct Baoquan He
2026-07-27 14:04   ` [RFC PATCH 03/11] mm, swap: add xswap cluster grow via VM_SPARSE vmalloc Baoquan He
2026-07-27 15:05     ` Nhat Pham
2026-07-27 16:09     ` Chris Li
2026-07-27 14:04   ` [RFC PATCH 04/11] mm, swap: add xswap grow trigger on cluster allocation Baoquan He
2026-07-27 14:04   ` [RFC PATCH 05/11] mm, swap: add xswap_try_shrink and shrink trigger on cluster free Baoquan He
2026-07-27 14:04   ` [RFC PATCH 06/11] mm, swap: free backing pages in xswap_unmap_clusters Baoquan He
2026-07-27 14:04   ` [RFC PATCH 07/11] mm, swap: add nr_free_tail for O(1) xswap shrink detection Baoquan He
2026-07-27 14:04   ` [RFC PATCH 08/11] mm, swap: add adjustable runtime ceiling (nr_clusters) for xswap Baoquan He
2026-07-27 14:05   ` [RFC PATCH 09/11] mm, swap: add debugfs knob for xswap per-device cluster limit Baoquan He
2026-07-27 14:05   ` [RFC PATCH 10/11] mm, swap: defer xswap shrink to workqueue to avoid lock recursion Baoquan He
2026-07-27 14:05   ` [RFC PATCH 11/11] mm, swap: serialize xswap map/unmap with a mutex Baoquan He
2026-07-27 15:13     ` Nhat Pham
2026-07-27 15:26   ` [RFC PATCH 02/11] mm, swap: add CONFIG_XSWAP and xswap fields to swap_info_struct Chris Li
2026-07-27 15:48 ` [RFC PATCH 00/11] mm, swap: dynamic cluster management for xswap devices Nhat Pham

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox