RFC mm: store zswap entries in swap table (Pointer entry)
Get series with b4
b4 am [email protected]Versions newest first
- v1 RFC Latest7 patches 4 repliesIn review
Patches in v1 No applies recorded yet
| # | Subject and files | Size | Replies | Applied |
|---|---|---|---|---|
| 1/7 | mm/swap_table: add Pointer type support for zswap entry storagemm/ | +31 | 0 replies | |
| 2/7 | mm/zswap: add swp_tb_val to zswap_entry and Pointer accessor helpersmm/ mm/ | +114 | 0 replies | |
| 3/7 | mm/swap_state: do zswap conversion in __swap_cache_do_del_foliomm/ mm/ mm/ | +47 | 0 replies | |
| 4/7 | mm/zswap, mm/swap_state: handle Pointer entries in add_folio pathmm/ mm/ mm/ | +111 | 0 replies | |
| 5/7 | mm/swapfile: handle Pointer entries in count/dup/put pathsmm/ mm/ | +81 | 0 replies | |
| 6/7 | mm/zswap, mm/swap_state: migrate zswap to use swap_table for entry indexingmm/ mm/ | +97 | 0 replies | |
| 7/7 | mm/zswap, mm/swap_state: replace xarray indexing with swap table lookupsinclude/ mm/ mm/ +3 more | +165 | 0 replies |
Reviews trailers per patch
No Reviewed-by, Acked-by or Tested-by trailers for v1 yet.
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