public inbox for linux-block@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] zram: Optimize LZ4 dictionary compression performance
@ 2026-03-13  2:41 gao xu
  2026-03-13  3:00 ` Sergey Senozhatsky
  0 siblings, 1 reply; 2+ messages in thread
From: gao xu @ 2026-03-13  2:41 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: Minchan Kim, Jens Axboe, linux-block@vger.kernel.org,
	linux-kernel@vger.kernel.org, Andrew Morton, surenb@google.com,
	zhouxiaolong

Calling `LZ4_loadDict()` repeatedly in Zram causes significant overhead
due to its internal dictionary pre-processing. This commit introduces a
template stream mechanism to pre-process the dictionary only once when
the dictionary is initially set or modified. It then efficiently copies
this state for subsequent compressions.

Verification Test Items:
Test Platform: android16-6.12
1. Collect Anonymous Page Dataset
1) Apply the following patch:
static bool zram_meta_alloc(struct zram *zram, u64 disksize)
	if (!huge_class_size)
-		huge_class_size = zs_huge_class_size(zram->mem_pool);
+		huge_class_size = 0;
2)Install multiple apps and monkey testing until SwapFree is close to 0.
3)Execute the following command to export data:
dd if=/dev/block/zram0 of=/data/samples/zram_dump.img bs=4K

2. Train Dictionary
Since LZ4 does not have a dedicated dictionary training tool, the zstd
tool can be used for training[1]. The command is as follows:
zstd --train /data/samples/* --split=4096 --maxdict=64KB -o /vendor/etc/dict_data

3. Test Code
adb shell "dd if=/data/samples/zram_dump.img of=/dev/test_pattern bs=4096 count=131072 conv=fsync"
adb shell "swapoff /dev/block/zram0"
adb shell "echo 1 > /sys/block/zram0/reset"
adb shell "echo lz4 > /sys/block/zram0/comp_algorithm"
adb shell "echo dict=/vendor/etc/dict_data   >  /sys/block/zram0/algorithm_params"
adb shell "echo 6G > /sys/block/zram0/disksize"
echo "Start Compression"
adb shell "taskset 80 dd if=/dev/test_pattern of=/dev/block/zram0 bs=4096 count=131072 conv=fsync"
echo.
echo "Start Decompression"
adb shell "taskset 80 dd if=/dev/block/zram0 of=/dev/output_result bs=4096 count=131072 conv=fsync"
echo "mm_stat:"
adb shell "cat /sys/block/zram0/mm_stat"
echo.
Note: To ensure stable test results, it is best to lock the CPU frequency
before executing the test.

LZ4 supports dictionaries up to 64KB. Below are the test results for
compression rates at various dictionary sizes:
dict_size          base        patch
  4 KB          156M/s      219M/s
  8 KB          136M/s      217M/s
 16KB           98M/s       214M/s
 32KB           66M/s       225M/s
 64KB           38M/s       224M/s

When an LZ4 compression dictionary is enabled, compression speed is
negatively impacted by the dictionary's size; larger dictionaries result
in slower compression. This patch eliminates the influence of dictionary
size on compression speed, ensuring consistent performance regardless of
dictionary scale.

[1] https://github.com/lz4/lz4?tab=readme-ov-file

Signed-off-by: gao xu <gaoxu2@honor.com>
---
v1 -> v2:
https://lore.kernel.org/linux-block/20260311084312.1766036-2-senozhatsky@chromium.org/
This patch ensures that the compression dictionary is set only during initialization,
removing code related to the compression dictionary changing during device operation.
Based on Sergey Senozhatsky's suggestions.

https://lore.kernel.org/linux-block/ae51966c3cb445e9983230243bb6a5b2@honor.com/
---
 drivers/block/zram/backend_lz4.c | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c
index 04e186614..c449d511b 100644
--- a/drivers/block/zram/backend_lz4.c
+++ b/drivers/block/zram/backend_lz4.c
@@ -14,13 +14,38 @@ struct lz4_ctx {
 
 static void lz4_release_params(struct zcomp_params *params)
 {
+	LZ4_stream_t *dict_stream = params->drv_data;
+
+	params->drv_data = NULL;
+	if (!dict_stream)
+		return;
+
+	kfree(dict_stream);
 }
 
 static int lz4_setup_params(struct zcomp_params *params)
 {
+	LZ4_stream_t *dict_stream;
+	int ret;
+
 	if (params->level == ZCOMP_PARAM_NOT_SET)
 		params->level = LZ4_ACCELERATION_DEFAULT;
 
+	if (!params->dict || !params->dict_sz)
+		return 0;
+
+	dict_stream = kzalloc_obj(*dict_stream, GFP_KERNEL);
+	if (!dict_stream)
+		return -ENOMEM;
+
+	ret = LZ4_loadDict(dict_stream,
+			   params->dict, params->dict_sz);
+	if (ret != params->dict_sz) {
+		kfree(dict_stream);
+		return -EINVAL;
+	}
+	params->drv_data = dict_stream;
+
 	return 0;
 }
 
@@ -79,9 +104,7 @@ static int lz4_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
 					zctx->mem);
 	} else {
 		/* Cstrm needs to be reset */
-		ret = LZ4_loadDict(zctx->cstrm, params->dict, params->dict_sz);
-		if (ret != params->dict_sz)
-			return -EINVAL;
+		memcpy(zctx->cstrm, params->drv_data, sizeof(*zctx->cstrm));
 		ret = LZ4_compress_fast_continue(zctx->cstrm, req->src,
 						 req->dst, req->src_len,
 						 req->dst_len, params->level);
--

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

end of thread, other threads:[~2026-03-13  3:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-13  2:41 [PATCH v2] zram: Optimize LZ4 dictionary compression performance gao xu
2026-03-13  3:00 ` Sergey Senozhatsky

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