Skip to content

RFC mm: store zswap entries in swap table (Pointer entry)

Baoquan He linux-mm lkml syzbot 1 version In review

Get series with b4
b4 am [email protected]

Versions newest first

  1. v1 RFC Latest7 patches 4 repliesIn review

Patches in v1 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/7mm/swap_table: add Pointer type support for zswap entry storagemm/swap_table.h+31 -40 replies
2/7mm/zswap: add swp_tb_val to zswap_entry and Pointer accessor helpersmm/swap.h mm/zswap.c+114 -00 replies
3/7mm/swap_state: do zswap conversion in __swap_cache_do_del_foliomm/swap.h mm/swap_state.c mm/zswap.c+47 -00 replies
4/7mm/zswap, mm/swap_state: handle Pointer entries in add_folio pathmm/swap.h mm/swap_state.c mm/zswap.c+111 -280 replies
5/7mm/swapfile: handle Pointer entries in count/dup/put pathsmm/swapfile.c mm/zswap.c+81 -190 replies
6/7mm/zswap, mm/swap_state: migrate zswap to use swap_table for entry indexingmm/swap_state.c mm/zswap.c+97 -520 replies
7/7mm/zswap, mm/swap_state: replace xarray indexing with swap table lookupsinclude/linux/zswap.h mm/page_io.c mm/swap.h +3 more+165 -2040 replies

Reviews trailers per patch

No Reviewed-by, Acked-by or Tested-by trailers for v1 yet.

Read the v1 thread

Cover letter [RFC PATCH 0/7] mm: store zswap entries in swap table (Pointer entry)

Currently zswap uses a per-swap-device xarray to map swap offsets to zswap_entry pointers. This introduces an additional tree walk on every zswap entry access.

This series replaces the xarray with a "Pointer" entry type stored directly in the swap cluster table. The new swp_tb_t variant embeds a zswap_entry pointer plus a entry count, eliminating the xarray and its lookup overhead entirely.

Design overview
---------------
A swap table slot can now be one of five types:

  NULL:    |---------------- 0 ---------------|
  Shadow:  |SWAP_COUNT|Z|---- SHADOW_VAL ---|1|
  PFN:     |SWAP_COUNT|Z|------ PFN -------|10|
  Pointer: |----------- Pointer ----------|100|
  Bad:     |------------- 1 -------------|1000|

When zswap compresses a page, it saves the original swap table entry (PFN or Shadow) in zswap_entry->swp_tb_val, then writes the Pointer entry into the swap table. The swap count and flags remain accessible via helper functions that read them from swp_tb_val.

The zswap_entry is threaded through the swapin call chain via a new void **zentry parameter, so zswap_load() receives it directly instead of doing an xarray lookup.

Performance
-----------
[~]# free -h
total used free shared buff/cache available

Mem:           3.8Gi       155Mi       3.4Gi       656Ki       315Mi       3.7Gi
Swap:          4.0Gi        54Mi       3.9Gi

Scalability benchmark: 'usemem -O -y -x -n 1 5G', 10 runs under cgroup MemoryMax=2G MemorySwapMax=3G. zswap enabled with zstd compressor.

Kernel A: cfb8731f5396 (xarray-based lookup, baseline) Kernel B: (Pointer entry)

5G test — the gap widens significantly as swap pressure grows:

     Metric           xarray(A)       Pointer(B)
    --------------------------------------------------
    Avg throughput      709,556 KB/s    792,681 KB/s  (+11.7%)
    Avg free time       167,994 µs     132,896 µs   (-20.9%)

Free time trend across 10 rounds at 5G:

    Pointer: 126→124→126→126→124→129→138→145→142→148  (gradual, +17%)
    xarray:  136→139→136→160→162→161→159→230→219→178  (collapse, +31%)

xarray degrades sharply in the later rounds (last 3 avg free time 209 ms vs Pointer's 145 ms, 1.44× worse) as the radix tree insertion/deletion cost grows non-linearly under sustained swap churn. Pointer entry avoids this entirely by looking up entries directly in the swap cluster table, which is already hot in cache.

Baoquan He (7):
mm/swap_table: add Pointer type support for zswap entry storage mm/zswap: add swp_tb_val to zswap_entry and Pointer accessor helpers mm/swap_state: do zswap conversion in __swap_cache_do_del_folio mm/zswap, mm/swap_state: handle Pointer entries in add_folio path mm/swapfile: handle Pointer entries in count/dup/put paths mm/zswap, mm/swap_state: migrate zswap to use swap_table for entry
indexing
mm/zswap, mm/swap_state: replace xarray indexing with swap table
lookups

 include/linux/zswap.h |   4 +-
 mm/page_io.c          |   4 +-
 mm/swap.h             |  52 +++++-
 mm/swap_state.c       | 117 +++++++++++---
 mm/swap_table.h       |  35 ++++-
 mm/swapfile.c         | 107 ++++++++++---
 mm/zswap.c            | 358 +++++++++++++++++++++++++++++-------------
 7 files changed, 508 insertions(+), 169 deletions(-)
Signature · 1 line
2.54.0