Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v4 0/3] mm/zswap: shrink zswap_entry via a fixed pool index
@ 2026-08-30 11:47 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
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Jianyue Wu @ 2026-08-30 11:47 UTC (permalink / raw)
  To: Johannes Weiner, Yosry Ahmed, Nhat Pham, Chengming Zhou,
	Andrew Morton
  Cc: Jianyue Wu, Chris Li, linux-mm, linux-kernel

Every stored page has a struct zswap_entry, so its size is pure per-page
overhead.  On x86_64 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 slot.

This series:

  1. Releases retired pools with queue_rcu_work() instead of
     synchronize_rcu() so the last put no longer blocks on an RCU grace
     period.
  2. Replaces the zswap_pools list with a fixed ZSWAP_MAX_POOLS (16)
     array and a separate RCU-protected current-pool pointer, giving
     each pool a stable slot index.  Slot 0 is left unused, and pool
     creation publishes the fully constructed pool directly into a free
     slot.
  3. Stores that u8 slot index 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 x86_64 (~2MiB of
     metadata saved per 1GiB of data held in zswap).

Runtime compressor switching is preserved, but the fixed array now
bounds the number of simultaneously live distinct compressor pools to 15
(slot 0 is reserved).  If all usable slots are full, creating a pool for
another compressor fails and the compressor switch is rejected.

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

  - zswap_entry object_size: 56 -> 48 bytes
  - e2e store+load median latency: no measurable regression vs baseline
    at matched stored_delta

The extra cost per store/free/decompress is one array-index load
instead of a pointer dereference.  With a single (or few) live pool(s)
that does not show up against (de)compression.

Testing
=======

- sizeof_check: 56 -> 48 bytes on x86_64
- Boot with DEBUG_ATOMIC_SLEEP + lockdep/PROVE_RCU + KASAN:
  zswap store/load and compressor switch (retire + reuse) pass

This series is based on akpm/mm-unstable as of 2026-08-30
(42d64d4fef83).

Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>

Changes since RFC v3:
  - Retire pools with queue_rcu_work() instead of call_rcu().
  - Queue the deferred RCU release work on system_percpu_wq.
  - Use rcu_dereference_check() with entry->pool_idx != 0 in
    zswap_entry_pool() instead of rcu_dereference_protected().
  - Simplify pool-slot publishing after confirming compressor parameter
    updates are serialized by the module parameter lock.

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 a fixed pools array
  mm/zswap: reference the pool by index to shrink struct zswap_entry

 mm/zswap.c | 140 ++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 101 insertions(+), 39 deletions(-)


base-commit: 42d64d4fef83a241c919c8693fdf0a21b2cb6061
-- 
2.43.0



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-09-03 12:59 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox