All of lore.kernel.org
 help / color / mirror / Atom feed
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



             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.