linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 00/17] zsmalloc/zram: there be preemption
@ 2025-02-21  9:37 Sergey Senozhatsky
  2025-02-21  9:37 ` [PATCH v7 01/17] zram: sleepable entry locking Sergey Senozhatsky
                   ` (16 more replies)
  0 siblings, 17 replies; 45+ messages in thread
From: Sergey Senozhatsky @ 2025-02-21  9:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Yosry Ahmed, Hillf Danton, Kairui Song,
	Sebastian Andrzej Siewior, Minchan Kim, linux-mm, linux-kernel,
	Sergey Senozhatsky

Currently zram runs compression and decompression in non-preemptible
sections, e.g.

    zcomp_stream_get()     // grabs CPU local lock
    zcomp_compress()

or

    zram_slot_lock()       // grabs entry spin-lock
    zcomp_stream_get()     // grabs CPU local lock
    zs_map_object()        // grabs rwlock and CPU local lock
    zcomp_decompress()

Potentially a little troublesome for a number of reasons.

For instance, this makes it impossible to use async compression
algorithms or/and H/W compression algorithms, which can wait for OP
completion or resource availability.  This also restricts what
compression algorithms can do internally, for example, zstd can
allocate internal state memory for C/D dictionaries:

do_fsync()
 do_writepages()
  zram_bio_write()
   zram_write_page()                          // become non-preemptible
    zcomp_compress()
     zstd_compress()
      ZSTD_compress_usingCDict()
       ZSTD_compressBegin_usingCDict_internal()
        ZSTD_resetCCtx_usingCDict()
         ZSTD_resetCCtx_internal()
          zstd_custom_alloc()                 // memory allocation

Not to mention that the system can be configured to maximize
compression ratio at a cost of CPU/HW time (e.g. lz4hc or deflate
with very high compression level) so zram can stay in non-preemptible
section (even under spin-lock or/and rwlock) for an extended period
of time.  Aside from compression algorithms, this also restricts what
zram can do.  One particular example is zram_write_page() zsmalloc
handle allocation, which has an optimistic allocation (disallowing
direct reclaim) and a pessimistic fallback path, which then forces
zram to compress the page one more time.

This series changes zram to not directly impose atomicity restrictions
on compression algorithms (and on itself), which makes zram write()
fully preemptible; zram read(), sadly, is not always preemptible yet.
There are still indirect atomicity restrictions imposed by zsmalloc().
One notable example is object mapping API, which returns with:
a) local CPU lock held
b) zspage rwlock held

First, zsmalloc's zspage lock is converted from rwlock to a special
type of RW-lookalike look with some extra guarantees/features.  Second,
a new handle mapping is introduced which doesn't use per-CPU buffers
(and hence no local CPU lock), does fewer memcpy() calls, but requires
users to provide a pointer to temp buffer for object copy-in (when
needed).  Third, zram is converted to the new zsmalloc mapping API
and thus zram read() becomes preemptible.

v6 -> v7:
-- provide dep_map access wrappers to avoid code duplication
   between !lockdep and lockdep builds (Yosry)

Sergey Senozhatsky (17):
  zram: sleepable entry locking
  zram: permit preemption with active compression stream
  zram: remove unused crypto include
  zram: remove max_comp_streams device attr
  zram: remove two-staged handle allocation
  zram: remove writestall zram_stats member
  zram: limit max recompress prio to num_active_comps
  zram: filter out recomp targets based on priority
  zram: rework recompression loop
  zsmalloc: rename pool lock
  zsmalloc: make zspage lock preemptible
  zsmalloc: introduce new object mapping API
  zram: switch to new zsmalloc object mapping API
  zram: permit reclaim in zstd custom allocator
  zram: do not leak page on recompress_store error path
  zram: do not leak page on writeback_store error path
  zram: add might_sleep to zcomp API

 Documentation/ABI/testing/sysfs-block-zram  |   8 -
 Documentation/admin-guide/blockdev/zram.rst |  36 +-
 drivers/block/zram/backend_zstd.c           |  11 +-
 drivers/block/zram/zcomp.c                  |  48 ++-
 drivers/block/zram/zcomp.h                  |   8 +-
 drivers/block/zram/zram_drv.c               | 289 ++++++++--------
 drivers/block/zram/zram_drv.h               |  22 +-
 include/linux/zsmalloc.h                    |   8 +
 mm/zsmalloc.c                               | 356 ++++++++++++++++----
 9 files changed, 498 insertions(+), 288 deletions(-)

--
2.48.1.601.g30ceb7b040-goog



^ permalink raw reply	[flat|nested] 45+ messages in thread
* [PATCH v6 00/17] zsmalloc/zram: there be preemption
@ 2025-02-14  4:50 Sergey Senozhatsky
  2025-02-14  4:50 ` [PATCH v6 01/17] zram: sleepable entry locking Sergey Senozhatsky
                   ` (16 more replies)
  0 siblings, 17 replies; 45+ messages in thread
From: Sergey Senozhatsky @ 2025-02-14  4:50 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Yosry Ahmed, Hillf Danton, Kairui Song, Minchan Kim, linux-mm,
	linux-kernel, Sergey Senozhatsky

Currently zram runs compression and decompression in non-preemptible
sections, e.g.

    zcomp_stream_get()     // grabs CPU local lock
    zcomp_compress()

or

    zram_slot_lock()       // grabs entry spin-lock
    zcomp_stream_get()     // grabs CPU local lock
    zs_map_object()        // grabs rwlock and CPU local lock
    zcomp_decompress()

Potentially a little troublesome for a number of reasons.

For instance, this makes it impossible to use async compression
algorithms or/and H/W compression algorithms, which can wait for OP
completion or resource availability.  This also restricts what
compression algorithms can do internally, for example, zstd can
allocate internal state memory for C/D dictionaries:

do_fsync()
 do_writepages()
  zram_bio_write()
   zram_write_page()                          // become non-preemptible
    zcomp_compress()
     zstd_compress()
      ZSTD_compress_usingCDict()
       ZSTD_compressBegin_usingCDict_internal()
        ZSTD_resetCCtx_usingCDict()
         ZSTD_resetCCtx_internal()
          zstd_custom_alloc()                 // memory allocation

Not to mention that the system can be configured to maximize
compression ratio at a cost of CPU/HW time (e.g. lz4hc or deflate
with very high compression level) so zram can stay in non-preemptible
section (even under spin-lock or/and rwlock) for an extended period
of time.  Aside from compression algorithms, this also restricts what
zram can do.  One particular example is zram_write_page() zsmalloc
handle allocation, which has an optimistic allocation (disallowing
direct reclaim) and a pessimistic fallback path, which then forces
zram to compress the page one more time.

This series changes zram to not directly impose atomicity restrictions
on compression algorithms (and on itself), which makes zram write()
fully preemptible; zram read(), sadly, is not always preemptible yet.
There are still indirect atomicity restrictions imposed by zsmalloc().
One notable example is object mapping API, which returns with:
a) local CPU lock held
b) zspage rwlock held

First, zsmalloc's zspage lock is converted from rwlock to a special
type of RW-lookalike look with some extra guarantees/features.  Second,
a new handle mapping is introduced which doesn't use per-CPU buffers
(and hence no local CPU lock), does fewer memcpy() calls, but requires
users to provide a pointer to temp buffer for object copy-in (when
needed).  Third, zram is converted to the new zsmalloc mapping API
and thus zram read() becomes preemptible.

v5 - > v6
- new zspage lock implementation, based on a spin-lock (Hillf)
- added CONFIG_LOCK_STAT support to zram entry lock and zspage lock
- tweaked lockdep names of zram entry lock and zspage lock
- factored out lockdep-enabled zram entry lock and zspage lock functions
  into separate helpers to avoid numerous #ifdef-s in the code (Andrew)
- updated zspage lock rules (Yosry)
- moved comp stream mutex initialisation out of cpu-up handler to
  close cpu-dead/stream-get/cpu-up race window (Yosry)
- dropped patches that factored out zspool and size-class locking
  (Yosry)
- rewrote commit messages for some patches (Yosry)

Sergey Senozhatsky (17):
  zram: sleepable entry locking
  zram: permit preemption with active compression stream
  zram: remove unused crypto include
  zram: remove max_comp_streams device attr
  zram: remove two-staged handle allocation
  zram: remove writestall zram_stats member
  zram: limit max recompress prio to num_active_comps
  zram: filter out recomp targets based on priority
  zram: rework recompression loop
  zsmalloc: rename pool lock
  zsmalloc: make zspage lock preemptible
  zsmalloc: introduce new object mapping API
  zram: switch to new zsmalloc object mapping API
  zram: permit reclaim in zstd custom allocator
  zram: do not leak page on recompress_store error path
  zram: do not leak page on writeback_store error path
  zram: add might_sleep to zcomp API

 Documentation/ABI/testing/sysfs-block-zram  |   8 -
 Documentation/admin-guide/blockdev/zram.rst |  36 +-
 drivers/block/zram/backend_zstd.c           |  11 +-
 drivers/block/zram/zcomp.c                  |  48 ++-
 drivers/block/zram/zcomp.h                  |   8 +-
 drivers/block/zram/zram_drv.c               | 326 ++++++++-------
 drivers/block/zram/zram_drv.h               |  22 +-
 include/linux/zsmalloc.h                    |   8 +
 mm/zsmalloc.c                               | 413 ++++++++++++++++----
 9 files changed, 592 insertions(+), 288 deletions(-)

--
2.48.1.601.g30ceb7b040-goog



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

end of thread, other threads:[~2025-02-21 22:29 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-21  9:37 [PATCH v7 00/17] zsmalloc/zram: there be preemption Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 01/17] zram: sleepable entry locking Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 02/17] zram: permit preemption with active compression stream Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 03/17] zram: remove unused crypto include Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 04/17] zram: remove max_comp_streams device attr Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 05/17] zram: remove two-staged handle allocation Sergey Senozhatsky
2025-02-21  9:37 ` [PATCH v7 06/17] zram: remove writestall zram_stats member Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 07/17] zram: limit max recompress prio to num_active_comps Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 08/17] zram: filter out recomp targets based on priority Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 09/17] zram: rework recompression loop Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 10/17] zsmalloc: rename pool lock Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 11/17] zsmalloc: make zspage lock preemptible Sergey Senozhatsky
2025-02-21 19:48   ` Yosry Ahmed
2025-02-21 19:52   ` Yosry Ahmed
2025-02-21 22:29     ` Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 12/17] zsmalloc: introduce new object mapping API Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 13/17] zram: switch to new zsmalloc " Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 14/17] zram: permit reclaim in zstd custom allocator Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 15/17] zram: do not leak page on recompress_store error path Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 16/17] zram: do not leak page on writeback_store " Sergey Senozhatsky
2025-02-21  9:38 ` [PATCH v7 17/17] zram: add might_sleep to zcomp API Sergey Senozhatsky
  -- strict thread matches above, loose matches on Subject: below --
2025-02-14  4:50 [PATCH v6 00/17] zsmalloc/zram: there be preemption Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 01/17] zram: sleepable entry locking Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 02/17] zram: permit preemption with active compression stream Sergey Senozhatsky
2025-02-20 19:10   ` Yosry Ahmed
2025-02-14  4:50 ` [PATCH v6 03/17] zram: remove unused crypto include Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 04/17] zram: remove max_comp_streams device attr Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 05/17] zram: remove two-staged handle allocation Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 06/17] zram: remove writestall zram_stats member Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 07/17] zram: limit max recompress prio to num_active_comps Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 08/17] zram: filter out recomp targets based on priority Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 09/17] zram: rework recompression loop Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 10/17] zsmalloc: rename pool lock Sergey Senozhatsky
2025-02-20 19:12   ` Yosry Ahmed
2025-02-14  4:50 ` [PATCH v6 11/17] zsmalloc: make zspage lock preemptible Sergey Senozhatsky
2025-02-20 19:18   ` Yosry Ahmed
2025-02-20 19:19     ` Yosry Ahmed
2025-02-21  1:20     ` Sergey Senozhatsky
2025-02-21 21:01       ` [PATCH v7 " Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 12/17] zsmalloc: introduce new object mapping API Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 13/17] zram: switch to new zsmalloc " Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 14/17] zram: permit reclaim in zstd custom allocator Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 15/17] zram: do not leak page on recompress_store error path Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 16/17] zram: do not leak page on writeback_store " Sergey Senozhatsky
2025-02-14  4:50 ` [PATCH v6 17/17] zram: add might_sleep to zcomp API Sergey Senozhatsky

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