Virtual swap collides with what memory.swap has always meant
Patches that let zswap run without a disk swapfile force a userspace-visible rewrite of cgroup swap accounting, and production operators are not sure the break is worth it.
A long-running effort to free zswap from physical swapfiles has run into something rarer than a performance argument: a core memory-management change that rewrites the meaning of a cgroup counter production fleets already steer on. Nhat Pham's virtual swap series, now in its sixth public revision on the swap-table design, lets anonymous pages hold a virtual swap entry in the page table while backing is resolved separately. Zswap and zero-filled pages no longer reserve disk slots they will never use, and machines with no swap storage at all can still compress anon memory. The cost is that memory.swap stops meaning what operators have assumed for years.
The technical through-line is straightforward. Today a swapped-out page consumes a disk slot even when the data lives only in zswap. Virtual swap inserts a vswap layer so allocation of a virtual entry is decoupled from acquisition of physical backing. Charge against memcg swap moves with that decoupling. Under the new rules, virtual swap entries count toward memory.swap.current only when they obtain physical swap slots; a cgroup can reclaim anon memory even with memory.swap.max set to 0 if zswap is allowed for it; and charge failure shifts from allocation time to writeback, where swap_writeout can return AOP_WRITEPAGE_ACTIVATE and zswap writeback can return -ENOMEM for a cgroup at its limit. Direct-mapped physical swap charging stays as it was. In cgroup v1, vswap entries still land on the memsw counter. Documentation for cgroup v2 is updated in lockstep, and new counters (nr_vswap in vmstat, vswap in memory.stat, plus debugfs used and alloc_reject totals) try to give userspace a way to see the new footprint.
Pham has been explicit that this is not a silent cleanup. "With vswap enabled, this changes what the counter means and when the charge can fail," the accounting patch states, and the design is opt-in behind a vswap kernel command-line parameter so that vswap=off leaves existing swap paths untouched. The series also carries related reclaim work: physical slots retained after a vswap folio's swap count hits zero while data remains in the swap cache are reclaimed from the physical scanner once swap is more than half full, because put-time reclaim is only best-effort. Metadata cost is under active reduction as well, including skipping memcg tables on physical clusters that only hold vswap backings and experimenting with a VM_SPARSE vmalloc array in place of per-cluster xarray storage.
That is the patch side. The debate side is whether redefining memory.swap is an acceptable ABI move. Pham, after roughly a year and ten revisions spanning an original design and a swap-table rewrite, plus a Linux Plumbers talk, has asked the wider (z)swap circle for a decision rather than another quiet respin. "I'd much rather work against a concrete objection than keep respinning into silence," he wrote to Kairui Song, Johannes Weiner, Yosry Ahmed, Chris Li, David Hildenbrand, Andrew Morton, and others. He lists the concessions already made: optionality at Kairui's request, a full rework onto swap table after the observation that further metadata shrinking would reinvent that format anyway, and overhead reductions driven by Chris Li's review.
Resistance is not primarily about the vswap mechanism. It is about interfaces and deployments that already treat swap limits as hard policy. Kairui Song has argued for a global, non-memcg limit on non-physical swap space, citing thin VMs run as pods with no internal cgroup limits that still need in-guest compression bounds, low-end devices that want a root-level cap, and Android's practical ceiling on ZRAM size where enlarging compression capacity produced serious application jank. Pham's concern on the other side is that exposing sizing "allows users to tune it and potentially misconfigure the system." Johannes Weiner has pushed back on the Android thrashing example by noting that Android already monitors PSI to kill under excessive pressure, which should catch over-compression; Suren Baghdasaryan was pulled in for a definitive view. Weiner has also been a design partner on the accounting shift itself, including the suggestion that OVERCOMMIT_GUESS allow a 3xRAM margin when vswap is on so swapfile-less zswap usage is not mistaken for overcommit failure.
Chris Li and others have kept pressure on process as much as on code: Asia-heavy swap maintainer distribution made proposed MM alignment slots contentious, mailing-list progress felt stalled, and there is still no settled list of what face-to-face conference discussion actually locked versus what remains open. Implementation direction is only partly converged. Kairui holds that VM_SPARSE is the right substrate and wants more comparative data; Pham is willing to rebase but asks why existing tested code must be dropped when a later switch does not look fundamentally blocked, and reports good results on swap-heavy production mixes of swap and zswap. Separate disagreements cover whether priority and other swap-shaped knobs should be overloaded for virtual capacity, and how far global limits should go when memcg already exists.
Google's production angle sits behind much of the caution even when it is not named in every reply. memory.swap.max set to zero is a real configuration used to forbid swapping while still allowing other reclaim behavior. If vswap lets zswap-backed reclaim proceed past that limit, jobs that believed they had pinned anon memory to RAM (or to a strict swap budget) observe different failure modes: writeback-time ENEMEM rather than allocation-time refusal, shrinkers skipping cgroups at the limit instead of walking their LRUs, and memory.swap.current that no longer tracks every swapped-looking page. The series tries to make the new world observable with vswap stat keys, but observability is not the same as compatibility. cgroup v1 memsw behavior is called out as unchanged for vswap entries, which may soften some older deployments and leave v2 operators carrying more of the semantic break.
Where things stand is awkwardly intermediate. Virtual swap is feature-complete enough to argue about ABI rather than mechanism. It is optional, documented, and instrumented. It is not merged, and the blocking questions are userspace-visible: may memory.swap mean "physical swap slots" instead of "swapped anon identity," may a zero swap max still admit zswap, and must global virtual-capacity limits exist for non-cgroupd workloads. Meetings keep slipping across time zones; the mailing list keeps restating the same forks. Until someone owns a concrete veto or an explicit "break it and document it" call, the series remains a rare case of core MM waiting on an ABI judgment rather than on another microbenchmark.