mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jianyue Wu <wujianyue000@gmail.com>
To: Johannes Weiner <hannes@cmpxchg.org>,
	Yosry Ahmed <yosry@kernel.org>, Nhat Pham <nphamcs@gmail.com>,
	Chengming Zhou <chengming.zhou@linux.dev>,
	Andrew Morton <akpm@linux-foundation.org>
Cc: Chris Li <chrisl@kernel.org>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [PATCH v5 0/3] mm/zswap: shrink zswap_entry via a pool id
Date: Fri,  4 Sep 2026 21:24:53 +0800	[thread overview]
Message-ID: <cover.1788528216.git.wujianyue000@gmail.com> (raw)
In-Reply-To: <20260830114731.8322-1-wujianyue000@gmail.com>

Every stored page has a struct zswap_entry, so its size is pure per-page
overhead.  On 64-bit it is currently 56 bytes, of which 8 bytes are a
pointer to the owning zswap_pool.

Only a handful of pools are ever live: a new pool is created only when
the compressor is (re)set, and pools are reused across compressor
switches.  That makes a per-entry pool pointer more expensive than it
needs to be, and the RCU list that currently tracks pools is more
machinery than this needs once each pool already has a stable id.

This series:

  1. Releases retired pools with queue_rcu_work() instead of a worker
     calling synchronize_rcu(), so the release worker no longer blocks
     on an RCU grace period.
  2. Replaces the zswap_pools list with an allocating xarray
     (XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_BH) and a separate RCU-protected
     current-pool pointer, giving each pool a stable small id.  Ids
     start at 1.  The reserved id 0 is never allocated, so looking it
     up resolves to NULL.  The table grows as needed up to 255 live
     pools (u8 pool_idx), not a fixed slot array.
  3. Stores that u8 pool id in each zswap_entry instead of the pool
     pointer.  The u8 fits in padding after the bool referenced field,
     so the entry shrinks from 56 to 48 bytes on 64-bit (~2MiB of
     metadata saved per 1GiB of data held in zswap).

Runtime compressor switching is preserved.  Pool ids are bounded to
1..255 because struct zswap_entry stores the id in a u8.  The cap
counts every id still in the xarray, including a killed pool that still
has entries.  Ids are reused when a pool is erased.  Switching back to
a compressor that still has a pool in the xarray resurrects it rather
than allocating a new id.  If all usable ids are full, creating a pool
for another compressor fails and the compressor switch is rejected.

On 64-bit, struct zswap_entry is 56 -> 48 bytes, which fits 73 -> 85
objects in a 4K slab.

Benchmark (x86_64, compressor=lzo, MADV_PAGEOUT store + fault-in load):

  - e2e store+load median latency: no measurable regression vs baseline
    at matched stored_delta

Each store, free, and decompress looks up the pool with xa_load()
instead of following a pointer.  With only a handful of live pools the
xarray walk is short.

Testing
=======

- Boot with DEBUG_ATOMIC_SLEEP + lockdep/PROVE_RCU + KASAN:
  zswap store/load, shrinker writeback, and compressor switch
  (retire, then switch back to resurrect) pass

This series is based on akpm/mm-unstable as of 2026-09-04
(20cab322c95c).

To: Johannes Weiner <hannes@cmpxchg.org>
To: Yosry Ahmed <yosry@kernel.org>
To: Nhat Pham <nphamcs@gmail.com>
To: Chengming Zhou <chengming.zhou@linux.dev>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Chris Li <chrisl@kernel.org>
Cc: linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>

Changes since RFC v4:
  - Replace the RCU pool list with an allocating xarray
    (XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_BH) and a separate RCU-protected
    current-pool pointer.
  - Resolve entry->pool_idx with xa_load() under rcu_read_lock().
  - Write pool_idx before the entry is stored in the swap tree, so a
    lookup cannot see a stale pool_idx left over from slab reuse.
  - Retire pools with queue_rcu_work() on system_percpu_wq.
  - Drop the RFC tag.

Link: https://lore.kernel.org/all/20260830114731.8322-1-wujianyue000@gmail.com/
Link: https://lore.kernel.org/all/20260815-shrink_zswap_entry_0815_v2-v3-3-0171bd86a667@gmail.com/
Link: https://lore.kernel.org/all/20260731-shrink_zswap_entry_v2-0-0-v2-0-e72083aa8734@gmail.com/
Link: https://lore.kernel.org/all/20260726-shrink_zswap_entry_v1-0-0-v1-1-30957e4d0cb6@gmail.com/

---
Jianyue Wu (3):
  mm/zswap: release retired pools via queue_rcu_work() instead of
    synchronize_rcu()
  mm/zswap: replace the zswap_pools list with an allocating xarray
  mm/zswap: reference the pool by id to shrink struct zswap_entry

 mm/zswap.c | 144 ++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 97 insertions(+), 47 deletions(-)


base-commit: 20cab322c95cea0327215bb81a05df69336032dd
-- 
2.43.0


  parent reply	other threads:[~2026-09-04 13:25 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-30 11:47 [RFC PATCH v4 0/3] mm/zswap: shrink zswap_entry via a fixed pool index Jianyue Wu
2026-08-30 11:47 ` [RFC PATCH v4 1/3] mm/zswap: release retired pools via queue_rcu_work() instead of synchronize_rcu() Jianyue Wu
2026-08-31 15:20   ` Yosry Ahmed
2026-09-01 14:33     ` Jianyue Wu
2026-09-01 15:38   ` Johannes Weiner
2026-09-02  0:53     ` Jianyue Wu
2026-08-30 11:47 ` [RFC PATCH v4 2/3] mm/zswap: replace the zswap_pools list with a fixed pools array Jianyue Wu
2026-08-31 15:28   ` Yosry Ahmed
2026-09-01 16:13   ` Johannes Weiner
2026-09-02  0:50     ` Jianyue Wu
2026-09-03 12:59       ` Jianyue Wu
2026-08-30 11:47 ` [RFC PATCH v4 3/3] mm/zswap: reference the pool by index to shrink struct zswap_entry Jianyue Wu
2026-08-31 15:30   ` Yosry Ahmed
2026-09-04 13:24 ` Jianyue Wu [this message]
2026-09-04 13:24   ` [PATCH v5 1/3] mm/zswap: release retired pools via queue_rcu_work() instead of synchronize_rcu() Jianyue Wu
2026-09-04 13:24   ` [PATCH v5 2/3] mm/zswap: replace the zswap_pools list with an allocating xarray Jianyue Wu
2026-09-04 16:04     ` Yosry Ahmed
2026-09-05 13:15       ` Jianyue Wu
2026-09-04 13:24   ` [PATCH v5 3/3] mm/zswap: reference the pool by id to shrink struct zswap_entry Jianyue Wu
2026-09-04 15:38     ` Yosry Ahmed
2026-09-05 13:20       ` Jianyue Wu

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=cover.1788528216.git.wujianyue000@gmail.com \
    --to=wujianyue000@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=chengming.zhou@linux.dev \
    --cc=chrisl@kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=nphamcs@gmail.com \
    --cc=yosry@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®