From: Sergey Senozhatsky <senozhatsky@chromium.org>
To: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Bo Zhang <zhangbo0325@gmail.com>,
akpm@linux-foundation.org, bgeffon@google.com,
minchan@kernel.org, richardycc@google.com, baohua@kernel.org,
linux-kernel@vger.kernel.org, linux-block@vger.kernel.org,
linux-mm@kvack.org
Subject: Re: [PATCH v3 10/11] zram: use rw_semaphore for decompression streams
Date: Thu, 15 Oct 2026 14:18:55 +0900 [thread overview]
Message-ID: <atBh9xfpOji_A7A_@google.com> (raw)
In-Reply-To: <atBAWZ3WZvat3UA1@google.com>
On (26/10/15 12:19), Sergey Senozhatsky wrote:
> Or perhaps we can avoid vm_map/unmap. A slightly different approach.
> kmalloc on fast path + memcpy (zsmalloc objects are strictly less than
> PAGE_SIZE bytes)
>
> Run #0: 1,475k IOPS, avg 3.26 us, stdev 14.24 us, p99.99 24.45 us, max 5,617 us (5.62 ms)
> Run #1: 1,472k IOPS, avg 3.27 us, stdev 15.35 us, p99.99 23.94 us, max 5,619 us (5.62 ms)
> Run #2: 1,473k IOPS, avg 3.29 us, stdev 15.37 us, p99.99 24.45 us, max 7,190 us (7.19 ms)
Just a better looking code (but same idea).
---
drivers/block/zram/zcomp.c | 47 +++++++++++++++++++++++++----------
drivers/block/zram/zcomp.h | 2 +-
drivers/block/zram/zram_drv.c | 2 +-
3 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 39d1f9384939..81f21bad787e 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -181,14 +181,13 @@ void zcomp_cstrm_put(struct zcomp_cstrm *zstrm)
mutex_unlock(&zstrm->lock);
}
-bool zcomp_shared_decomp(struct zcomp *comp, struct scatterlist *sg)
+bool zcomp_shared_decomp(struct zcomp *comp)
{
/*
* Shared decompression is only safe when the backend has no
- * mutable per-stream decompression context and the object is
- * contained within a single page (no ->local_copy bounce needed).
+ * mutable per-stream decompression context.
*/
- return !comp->ops->create_dctx && sg_is_last(sg);
+ return !comp->ops->create_dctx;
}
struct zcomp_dstrm *zcomp_dstrm_get(struct zcomp *comp,
@@ -244,6 +243,15 @@ int zcomp_compress(struct zcomp *comp, struct zcomp_cstrm *zstrm,
return ret;
}
+static int zcomp_decompress_buf(struct zcomp *comp, struct zcomp_dstrm *zstrm,
+ struct scatterlist *sg, void *buf,
+ struct zcomp_req *req)
+{
+ sg_copy_to_buffer(sg, 2, buf, req->src_len);
+ req->src = buf;
+ return comp->ops->decompress(comp->params, &zstrm->ctx, req);
+}
+
int zcomp_decompress(struct zcomp *comp, struct zcomp_dstrm *zstrm,
struct scatterlist *sg, unsigned int src_len, void *dst)
{
@@ -252,27 +260,40 @@ int zcomp_decompress(struct zcomp *comp, struct zcomp_dstrm *zstrm,
.src_len = src_len,
.dst_len = PAGE_SIZE,
};
- void *src = NULL;
+ void *src;
int ret;
might_sleep();
lockdep_assert_held(&zstrm->lock);
- if (!zcomp_shared_decomp(comp, sg))
+ if (!zcomp_shared_decomp(comp))
lockdep_assert_held(&zstrm->excl_lock);
if (sg_is_last(sg)) {
/* the object is contained within one page, read it in-place */
src = kmap_local_page(sg_page(sg));
req.src = src + sg->offset;
- } else {
- /* the object spans two pages, linearize it into local copy */
- sg_copy_to_buffer(sg, 2, zstrm->local_copy, src_len);
- req.src = zstrm->local_copy;
+ ret = comp->ops->decompress(comp->params, &zstrm->ctx, &req);
+ kunmap_local(src);
+ return ret;
}
- ret = comp->ops->decompress(comp->params, &zstrm->ctx, &req);
- if (src)
- kunmap_local(src);
+ /* exclusive mode already holds ->excl_lock */
+ if (!zcomp_shared_decomp(comp))
+ return zcomp_decompress_buf(comp, zstrm, sg, zstrm->local_copy,
+ &req);
+
+ /* shared mode: try a per-request bounce buffer first */
+ src = kmalloc(src_len, GFP_NOWAIT | __GFP_NOWARN);
+ if (src) {
+ ret = zcomp_decompress_buf(comp, zstrm, sg, src, &req);
+ kfree(src);
+ return ret;
+ }
+
+ /* fall back to ->local_copy serialized by ->excl_lock */
+ mutex_lock(&zstrm->excl_lock);
+ ret = zcomp_decompress_buf(comp, zstrm, sg, zstrm->local_copy, &req);
+ mutex_unlock(&zstrm->excl_lock);
return ret;
}
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
index 924c4185abe9..6764818d2a9f 100644
--- a/drivers/block/zram/zcomp.h
+++ b/drivers/block/zram/zcomp.h
@@ -115,7 +115,7 @@ void zcomp_destroy(struct zcomp *comp);
struct zcomp_cstrm *zcomp_cstrm_get(struct zcomp *comp);
void zcomp_cstrm_put(struct zcomp_cstrm *zstrm);
-bool zcomp_shared_decomp(struct zcomp *comp, struct scatterlist *sg);
+bool zcomp_shared_decomp(struct zcomp *comp);
struct zcomp_dstrm *zcomp_dstrm_get(struct zcomp *comp,
enum zcomp_dstrm_mode mode);
void zcomp_dstrm_put(struct zcomp_dstrm *zstrm, enum zcomp_dstrm_mode mode);
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index ad244624d4a5..e608769bfad5 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -2128,7 +2128,7 @@ static int read_compressed_page(struct zram *zram, struct page *page,
prio = get_slot_comp_priority(zram, index);
zs_obj_read_sg_begin(zram->mem_pool, handle, sg, size);
- if (zcomp_shared_decomp(zram->comps[prio], sg))
+ if (zcomp_shared_decomp(zram->comps[prio]))
mode = ZCOMP_DSTRM_SHARED;
zstrm = zcomp_dstrm_get(zram->comps[prio], mode);
--
2.56.0.385.gd3acb90ef8-goog
next prev parent reply other threads:[~2026-10-15 5:19 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-13 3:50 [PATCH v3 00/11] zram: redesign zcomp and rework backends Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 01/11] zram: prefix backends printk-s Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 02/11] zram: remove debugfs entry on init failure Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 03/11] zram: zstd: do not allocate empty C/D-dictionaries Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 04/11] zram: lz4hc: pre-initialize dictionary stream in setup_params Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 05/11] zram: lz4: use LZ4_decompress_safe_usingDict() Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 06/11] zram: lz4hc: " Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 07/11] zram: zstd: do not use kvzalloc() for zstd allocations Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 08/11] zram: reset writeback state in zram_reset_device() Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 09/11] zram: split zcomp into separate R/W streams Sergey Senozhatsky
2026-10-13 3:50 ` [PATCH v3 10/11] zram: use rw_semaphore for decompression streams Sergey Senozhatsky
2026-10-14 15:36 ` Bo Zhang
2026-10-14 20:46 ` Barry Song
2026-10-15 2:04 ` Sergey Senozhatsky
2026-10-15 3:19 ` Bo Zhang
2026-10-15 3:24 ` Sergey Senozhatsky
2026-10-15 1:41 ` Sergey Senozhatsky
2026-10-15 2:11 ` Sergey Senozhatsky
2026-10-15 3:19 ` Sergey Senozhatsky
2026-10-15 5:18 ` Sergey Senozhatsky [this message]
2026-10-15 11:24 ` Bo Zhang
2026-10-13 3:50 ` [PATCH v3 11/11] zram: use a singleton compression context for recompression Sergey Senozhatsky
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=atBh9xfpOji_A7A_@google.com \
--to=senozhatsky@chromium.org \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=bgeffon@google.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=minchan@kernel.org \
--cc=richardycc@google.com \
--cc=zhangbo0325@gmail.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.