From: Baoquan He <baoquan.he@linux.dev>
To: linux-mm@kvack.org
Cc: akpm@linux-foundation.org, hannes@cmpxchg.org, yosry@kernel.org,
nphamcs@gmail.com, chengming.zhou@linux.dev, chrisl@kernel.org,
kasong@tencent.com, shikemeng@huaweicloud.com, baohua@kernel.org,
youngjun.park@lge.com, linux-kernel@vger.kernel.org,
Baoquan He <baoquan.he@linux.dev>
Subject: [RFC PATCH 0/7] mm: store zswap entries in swap table (Pointer entry)
Date: Tue, 7 Jul 2026 15:31:57 +0800 [thread overview]
Message-ID: <20260707073215.72183-1-baoquan.he@linux.dev> (raw)
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(-)
--
2.54.0
next reply other threads:[~2026-07-07 7:32 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-07 7:31 Baoquan He [this message]
2026-07-07 7:31 ` [RFC PATCH 1/7] mm/swap_table: add Pointer type support for zswap entry storage Baoquan He
2026-07-07 7:31 ` [RFC PATCH 2/7] mm/zswap: add swp_tb_val to zswap_entry and Pointer accessor helpers Baoquan He
2026-07-07 7:32 ` [RFC PATCH 3/7] mm/swap_state: do zswap conversion in __swap_cache_do_del_folio Baoquan He
2026-07-07 7:32 ` [RFC PATCH 4/7] mm/zswap, mm/swap_state: handle Pointer entries in add_folio path Baoquan He
2026-07-07 7:32 ` [RFC PATCH 5/7] mm/swapfile: handle Pointer entries in count/dup/put paths Baoquan He
2026-07-07 7:32 ` [RFC PATCH 6/7] mm/zswap, mm/swap_state: migrate zswap to use swap_table for entry indexing Baoquan He
2026-07-07 7:32 ` [RFC PATCH 7/7] mm/zswap, mm/swap_state: replace xarray indexing with swap table lookups Baoquan He
2026-07-07 19:27 ` [RFC PATCH 0/7] mm: store zswap entries in swap table (Pointer entry) Nhat Pham
2026-07-07 19:49 ` Yosry Ahmed
2026-07-07 22:17 ` Nhat Pham
2026-07-07 21:32 ` [syzbot ci] " syzbot ci
2026-07-13 15:25 ` [RFC PATCH 0/7] " Nhat Pham
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260707073215.72183-1-baoquan.he@linux.dev \
--to=baoquan.he@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=chengming.zhou@linux.dev \
--cc=chrisl@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=kasong@tencent.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nphamcs@gmail.com \
--cc=shikemeng@huaweicloud.com \
--cc=yosry@kernel.org \
--cc=youngjun.park@lge.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.