Path forward for Virtualized Swap?

From: Nhat Pham

Date: Fri Sep 04 2026 - 17:15:39 EST


To Kairui, Johannes, Yosry, Chris, David, Andrew, and other (z)swap folks -
I need some help here.

I'd like to ask for a decision, or failing that, the specific thing that
would get us to one. I'd much rather work against a concrete objection than
keep respinning into silence.

Quick recap: today a swapped-out page holds a disk slot even when the data
never reaches disk, like zswap or zero-filled pages. My patch series
(latest version at [10]) puts a virtual entry in the page table instead and
resolves the backing separately, so zswap stops reserving disk it never
uses and can work on machines with no storage swap space at all.

I've been working on this since April 2025, going through 10 revisions (6
on the original design ([1] through [6]) and 4 on the swap-table-based
rewrite ([7] through [10])). I also gave a talk on it at LPC [11].

Throughout the process, I've been very receptive to reviewers - including
parties whose use cases are very different from my own, like zram users and
the ghost-swapfile-style deployments that want zswap with no backing disk
at all - and the current design reflects that:

* Kairui asked that this be optional, not a replacement [12]. It is now:
vswap is opt-in behind the vswap= cmdline parameter, and with vswap=off
the existing swap paths aren't touched at all.

* Kairui also pointed out that if I kept shrinking the metadata I'd "end up
reimplementing the swap table format" [12]. I took that feedback, and
reworked the entire series on top of swap table.

* Per Chris' requests, I've figured out ways to minimize memory overhead
[13]. On a zswap-only setup there's almost 0 overhead now, because the
vtable is merged with zswap's xarray rather than sitting on top of it.
The indirection is paid for by the tree we delete.

* Johannes pointed out that a physical cluster backing only vswap entries
still had to allocate a memcg_table, which was an overhead regression
against my older design on the zswap writeback case [14] (since a swap
entry occupies multiple levels). I've also fixed this.

* I've spent a lot of time chasing regressions on setups we don't even run
at Meta - zram in particular [6]. And if anyone's still worried after all
that, vswap=off keeps the old swap code available.

Numbers are in the v4 cover letter [10]. In terms of performance, vswap is
on par or better than baseline on zswap across memhog, usemem and kernel
build, and vswap=off tracks baseline within noise. I've even included an
A/B experiment on a real production workload (Instagram/django): throughput
on par, latency slightly better, and the swapfile footprint for every zswap
user on the host goes away.

Now, on xswap. Baoquan's working on a series [15] that covers some of the
same ground, and the VM_SPARSE cluster_info idea in it is genuinely good.
I've been reviewing that lineage since July [16] and I'd like whatever
lands to end up with the best parts of both. From my perspective the
differences are:

1. Userspace knobs. xswap asks the admin for a size (a percent of RAM) plus
a per-device limit to tune afterwards. I'm not aware of any use case
that needs those, and I don't think users have a good way to answer the
question anyway - sizing swap for compressed memory depends on memory
size, workload, and compression ratio all at once. That's precisely the
provisioning problem vswap exists to remove. The kernel should be as
transparent and dynamic as possible here, and not add knobs unless
there's a use case for them.

2. Writeback support. Writeback is core functionality for zswap, not an
add-on, and a design needs to account for it from the start. This came
up before, in the discussion around Chris' ghost swapfile RFC [17]: for
a solution here to be acceptable, it has to work with the primary
usecase and support disk writeback. Without it, whatever zswap won't
take (incompressible pages especially) has nowhere to go, and cold
compressed data can never leave RAM.

3. Cgroup charging behavior. vswap/xswap shouldn't be charged against the
swap usage counter. It's fundamentally a different resource from
physical swapfile space, and memory.swap.* should read 0 when nothing is
on disk [18]. I made the longer argument for this in [19].

4. Data structure (xarray vs sparse vmalloc array). Even with xarray, vswap
is already on par with or beating baseline. I like the sparse array
idea, but why are we landing an optimization before the feature itself,
without any A/B data showing the difference matters?

One thing I do want to be clear about: I'm glad other people care about
this problem. Chris' ghost swapfile and Baoquan's xswap are both going
after the same set of problems, and that's a good sign. It means this is
real and shared, not something only Meta runs into.

What's been harder is the shape of the engagement. Alternatives keep
getting posted and pushed that don't cover all the requirements, while this
series sits without review. I don't think I'm owed anyone's interest in the
problems I care about. But I do think working code, with benchmarks and
production exposure behind it, deserves a fair hearing next to in-progress
proposals.

So what I'm asking for: I'd like us to converge rather than keep two series
in flight. My preference is that we land vswap first, then build Baoquan's
sparse array on top of it as an optimization. That gets the feature in, and
by then we'd have the A/B data to show whether the sparse array actually
beats the xarray.

If you think that's the wrong order, I'd genuinely like to understand why -
after 17 months and 10 revisions I still don't have a clear picture of the
objection.

[1] https://lore.kernel.org/all/20250407234223.1059191-1-nphamcs@xxxxxxxxx/
[2] https://lore.kernel.org/all/20250429233848.3093350-1-nphamcs@xxxxxxxxx/
[3] https://lore.kernel.org/all/20260208215839.87595-1-nphamcs@xxxxxxxxx/
[4] https://lore.kernel.org/all/20260318222953.441758-1-nphamcs@xxxxxxxxx/
[5] https://lore.kernel.org/all/20260320192735.748051-1-nphamcs@xxxxxxxxx/
[6] https://lore.kernel.org/all/20260505153854.1612033-1-nphamcs@xxxxxxxxx/
[7] https://lore.kernel.org/all/20260528212955.1912856-1-nphamcs@xxxxxxxxx/
[8] https://lore.kernel.org/all/20260612193738.2183968-1-nphamcs@xxxxxxxxx/
[9] https://lore.kernel.org/all/20260806184254.3790858-1-nphamcs@xxxxxxxxx/
[10] https://lore.kernel.org/all/20260825153238.2695446-1-nphamcs@xxxxxxxxx/
[11] https://lwn.net/Articles/1016136/
[12] https://lore.kernel.org/all/CAMgjq7AQNGK-a=AOgvn4-V+zGO21QMbMTVbrYSW_R2oDSLoC+A@xxxxxxxxxxxxxx/
[13] https://lore.kernel.org/all/CACePvbVXQWgcPD-bgK7iDba4NFLo2tT89ZbLOa03maJU4er4ag@xxxxxxxxxxxxxx/
[14] https://lore.kernel.org/all/aZyFxKGXc8J6PIij@xxxxxxxxxxx/
[15] https://lore.kernel.org/all/20260827094509.1016740-1-hebaoquan@xxxxxxxxxx/
[16] https://lore.kernel.org/lkml/CAKEwX=Pe+qMZd2xhnU-PAGQtgXkp56c-JwYCbt2Lux9htgB67Q@xxxxxxxxxxxxxx/
[17] https://lore.kernel.org/all/20251121114011.GA71307@xxxxxxxxxxx/
[18] https://lore.kernel.org/all/anYIboHEUZb4fhHv@xxxxxxxxxxx/
[19] https://lore.kernel.org/all/CAKEwX=P4syV38jAVCWq198r2OHXXc=xA-fx1dk6+qYef6yzxWQ@xxxxxxxxxxxxxx/