Re: [PATCH 00/16] xswap: extendable swap device backed by zswap

From: Nhat Pham

Date: Wed Sep 02 2026 - 10:42:17 EST


On Thu, Aug 27, 2026 at 5:45 AM Baoquan He <hebaoquan@xxxxxxxxxx> wrote:

Ah I think I used the wrong msg-id in my other response:

https://lore.kernel.org/all/CAKEwX=OW6M5n8u3L_oigD3Ffn_BcB2L7p=ROfmJCxMKQFH7tXg@xxxxxxxxxxxxxx/

My bad. I'll recap my comments here for your convenience.

>
> xswap is an extendable swap device with no backing storage. Swapped-out
> pages live only in zswap, so the device wastes no disk space and its
> size is independent of any physical device.
>
> xswap decouples PTE swap entries from physical backing storage. The
> cluster_info array is backed by a sparse vmalloc (VM_SPARSE) area that is
> grown and shrunk on demand:
>
> - Grow: when cluster allocation runs out of free clusters and the device
> is below its ceiling, more physical pages are mapped into the VM_SPARSE
> area and their clusters are added to the free list.
>
> - Shrink: when contiguous free clusters accumulate at the tail of the
> mapped range (tracked in O(1) via nr_free_tail), they are unmapped and
> the backing pages freed. Shrink is deferred to a workqueue to avoid
> lock recursion.
>
> A per-device ceiling (nr_clusters) bounds growth and is adjustable at
> runtime via debugfs.
>
> Interface:
>
> /sys/kernel/mm/xswap/create write "<percent> [<prio>]" to
> create a device; percent is a
> percent of RAM (0 for the default),
> prio is an optional swap priority
> (default DEF_SWAP_PRIO)
> /sys/kernel/mm/xswap/destroy write a swap type to tear down
> a device
> /sys/kernel/debug/xswap/type<N>_cluster_limit
> read/write the per-device
> cluster ceiling
>
> Since xswap has no backing, swapped-out pages are stored compressed in
> zswap: physical writeout is skipped, and zswap writeback is disabled when
> every swapfile in the system is an xswap device. xswap requires zswap, so
> device creation is refused when zswap is unavailable.
>
> Naming:
> ======
> I'm going with "xswap" (the "x" for extendable/extension) rather than "vswap".
> Chris suggested this name, and this aligns with the "VFS-like swap layers"
> direction Chris Li described in the first swap abstraction LPC talk
> (co-hosted with Yosry) the swap ops and the xswap extension interfaces in
> this series are moving toward exactly that. I don't have a strong preference
> between xswap and vswap, so if reviewers object to the name, please comment.
>
> Note:
> =====
> This patchset only build the base. On top of this, the subsequent core code
> implementation of xswap writeback, rmap etc can be done more easily. E.g, we
> only need add one field in struct swap_cluster_info to let xs_table point to
> physical swap entry, or zswap entry etc. On top of this patchset, no need to
> stir core data structure too much or introduce extra data structure.

It's functionally equivalent. I think it looks cleaner to separate
vswap-only bits into a vswap-only struct (technically saving 1 word
for the cluster that doesnt need it too).

That aside, how would writeback, rmap be simpler? The complexity comes
from the operations around it, not the actual vtable/xs_table
operations itself.


>
> --- a/mm/swap.h
> +++ b/mm/swap.h
> @@ -57,6 +57,9 @@ struct swap_cluster_info {
> u8 order;
> atomic_long_t __rcu *table; /* Swap table entries, see mm/swap_table.h */
> unsigned int *extend_table; /* For large swap count, protected by ci->lock */
> +#ifdef CONFIG_XSWAP
> + unsigned long *xs_table;
> +#endif
>
> Testing (taken on qemu kvm guest with 8G memory):
> =========
> 1. enable zswap and create/destroy xswap device
> ~# echo 0 > /sys/kernel/mm/xswap/create
> -bash: echo: write error: Operation not supported
> ~# echo 1 > /sys/module/zswap/parameters/enabled
> ~# echo 0 > /sys/kernel/mm/xswap/create
> ~# swapon
> NAME TYPE SIZE USED PRIO
> xswap0 xswap 2.3G 0B -1
> ~# echo 0 > /sys/kernel/mm/xswap/destroy
> ~# swapon
>
> 2. create xswap device and tune the zswap size
>
> ~# echo "50 10" > /sys/kernel/mm/xswap/create
> ~# echo 0 > /sys/kernel/mm/xswap/create
> ~# swapon
> NAME TYPE SIZE USED PRIO
> xswap0 xswap 3.9G 0B 10
> xswap1 xswap 2.3G 0B -1
>
> ~# cat /sys/kernel/debug/xswap/type0_cluster_limit
> 1990
> ~# cat /sys/kernel/debug/xswap/type1_cluster_limit
> 1194
> ~# echo 2048 > /sys/kernel/debug/xswap/type0_cluster_limit
> ~# echo 2048 > /sys/kernel/debug/xswap/type1_cluster_limit
> ~# swapon
> NAME TYPE SIZE USED PRIO
> xswap0 xswap 4G 0B 10
> xswap1 xswap 4G 0B -1
>
> 3. under heavy memory pressure tune swap size or destroy xswap device
>
> ~# stress-ng --vm 1 --vm-bytes 8G --vm-keep --timeout 120s &
>
> ~# echo 1024 > /sys/kernel/debug/xswap/type0_cluster_limit
> ~# swapon
> NAME TYPE SIZE USED PRIO
> xswap0 xswap 2G 2.6G 10
> xswap1 xswap 4G 182M -1
> ~# echo 1024 > /sys/kernel/debug/xswap/type1_cluster_limit
> ~# swapon
> NAME TYPE SIZE USED PRIO
> xswap0 xswap 2G 1.4G 10
> xswap1 xswap 2G 315.4M -1
>
> ~# echo 0 > /sys/kernel/mm/xswap/destroy
> ~# swapon
> NAME TYPE SIZE USED PRIO
> xswap1 xswap 2G 1.1G -1
>
> I tried create/destroy and grow/shrink xswap device under heavy
> memory pressure, all passed.

We have something that has performance benchmarks, including on a
real, production workload:

https://lore.kernel.org/all/20260825153238.2695446-1-nphamcs@xxxxxxxxx/

And somehow, we decide to implement a different data structures,
without concrete numbers to show that it is more efficient than xarray
(only intuitions)?

At the risk of sounding like a broken record - I have to ask: why
don't we land use case first, optimize later? Especially since, we
have data showing that performance is fairly close (better in some
aspects in fact), AND users who do not want to risk it still have the
old code and can do A/B testing before they decide to switch?

A lot of the complexity in this patch series comes from the fact that
you don't get a lot of what xarray gives you out of the box. Which is
fine for an optimization, but I don't see any A/B data to compare?
Doesn't that sound like pre-mature optimization?