* [PATCHv7 00/24] zram: introduce custom comp backends API
@ 2024-09-02 10:55 Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 01/24] lib: zstd: export API needed for dictionary support Sergey Senozhatsky
` (23 more replies)
0 siblings, 24 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
This series introduces support for run-time compression algorithms
tuning, so users, for instance, can adjust compression/acceleration
levels and provide pre-trained compression/decompression dictionaries
which certain algorithms support.
At this point we stop supporting (old/deprecated) comp API. We may
add new acomp API support in the future, but before that zram needs
to undergo some major rework (we are not ready for async compression).
Some benchmarks for reference (look at column #2)
*** init zstd
/sys/block/zram0/mm_stat
1750659072 504622188 514355200 0 514355200 1 0 34204 34204
*** init zstd dict=/home/ss/zstd-dict-amd64
/sys/block/zram0/mm_stat
1750650880 465908890 475398144 0 475398144 1 0 34185 34185
*** init zstd level=8 dict=/home/ss/zstd-dict-amd64
/sys/block/zram0/mm_stat
1750654976 430803319 439873536 0 439873536 1 0 34185 34185
*** init lz4
/sys/block/zram0/mm_stat
1750646784 664266564 677060608 0 677060608 1 0 34288 34288
*** init lz4 dict=/home/ss/lz4-dict-amd64
/sys/block/zram0/mm_stat
1750650880 619990300 632102912 0 632102912 1 0 34278 34278
*** init lz4hc
/sys/block/zram0/mm_stat
1750630400 609023822 621232128 0 621232128 1 0 34288 34288
*** init lz4hc dict=/home/ss/lz4-dict-amd64
/sys/block/zram0/mm_stat
1750659072 505133172 515231744 0 515231744 1 0 34278 34278
Recompress
init zram zstd (prio=0), zstd level=5 (prio 1), zstd with dict (prio 2)
*** zstd
/sys/block/zram0/mm_stat
1750982656 504630584 514269184 0 514269184 1 0 34204 34204
*** idle recompress priority=1 (zstd level=5)
/sys/block/zram0/mm_stat
1750982656 488645601 525438976 0 514269184 1 0 34204 34204
*** idle recompress priority=2 (zstd dict)
/sys/block/zram0/mm_stat
1750982656 460869640 517914624 0 514269184 1 0 34185 34204
v6..v7
-- new device attribute algorithm_params to tune and tweak algorithms
(instead of extending comp_algorithm/recomp_algorithm attributes)
-- added missing sysfs file documentation
-- reshufleed docuemntation a tad
-- recompress device attr now accepts priority argument
Sergey Senozhatsky (24):
lib: zstd: export API needed for dictionary support
lib: lz4hc: export LZ4_resetStreamHC symbol
lib: zstd: fix null-deref in ZSTD_createCDict_advanced2()
zram: introduce custom comp backends API
zram: add lzo and lzorle compression backends support
zram: add lz4 compression backend support
zram: add lz4hc compression backend support
zram: add zstd compression backend support
zram: pass estimated src size hint to zstd
zram: add zlib compression backend support
zram: add 842 compression backend support
zram: check that backends array has at least one backend
zram: introduce zcomp_params structure
zram: recalculate zstd compression params once
zram: introduce algorithm_params device attribute
zram: add support for dict comp config
zram: introduce zcomp_req structure
zram: introduce zcomp_ctx structure
zram: move immutable comp params away from per-CPU context
zram: add dictionary support to lz4
zram: add dictionary support to lz4hc
zram: add dictionary support to zstd backend
Documentation/zram: add documentation for algorithm parameters
zram: support priority parameter in recompression
Documentation/ABI/testing/sysfs-block-zram | 7 +
Documentation/admin-guide/blockdev/zram.rst | 64 ++++--
drivers/block/zram/Kconfig | 76 +++++--
drivers/block/zram/Makefile | 8 +
drivers/block/zram/backend_842.c | 61 ++++++
drivers/block/zram/backend_842.h | 10 +
drivers/block/zram/backend_deflate.c | 146 +++++++++++++
drivers/block/zram/backend_deflate.h | 10 +
drivers/block/zram/backend_lz4.c | 127 +++++++++++
drivers/block/zram/backend_lz4.h | 10 +
drivers/block/zram/backend_lz4hc.c | 128 +++++++++++
drivers/block/zram/backend_lz4hc.h | 10 +
drivers/block/zram/backend_lzo.c | 59 +++++
drivers/block/zram/backend_lzo.h | 10 +
drivers/block/zram/backend_lzorle.c | 59 +++++
drivers/block/zram/backend_lzorle.h | 10 +
drivers/block/zram/backend_zstd.c | 226 ++++++++++++++++++++
drivers/block/zram/backend_zstd.h | 10 +
drivers/block/zram/zcomp.c | 194 +++++++++--------
drivers/block/zram/zcomp.h | 71 ++++--
drivers/block/zram/zram_drv.c | 136 +++++++++++-
drivers/block/zram/zram_drv.h | 1 +
include/linux/zstd.h | 167 +++++++++++++++
lib/lz4/lz4hc_compress.c | 1 +
lib/zstd/compress/zstd_compress.c | 2 +
lib/zstd/zstd_compress_module.c | 49 +++++
lib/zstd/zstd_decompress_module.c | 36 ++++
27 files changed, 1544 insertions(+), 144 deletions(-)
create mode 100644 drivers/block/zram/backend_842.c
create mode 100644 drivers/block/zram/backend_842.h
create mode 100644 drivers/block/zram/backend_deflate.c
create mode 100644 drivers/block/zram/backend_deflate.h
create mode 100644 drivers/block/zram/backend_lz4.c
create mode 100644 drivers/block/zram/backend_lz4.h
create mode 100644 drivers/block/zram/backend_lz4hc.c
create mode 100644 drivers/block/zram/backend_lz4hc.h
create mode 100644 drivers/block/zram/backend_lzo.c
create mode 100644 drivers/block/zram/backend_lzo.h
create mode 100644 drivers/block/zram/backend_lzorle.c
create mode 100644 drivers/block/zram/backend_lzorle.h
create mode 100644 drivers/block/zram/backend_zstd.c
create mode 100644 drivers/block/zram/backend_zstd.h
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 01/24] lib: zstd: export API needed for dictionary support
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 02/24] lib: lz4hc: export LZ4_resetStreamHC symbol Sergey Senozhatsky
` (22 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky, Nick Terrell
We need to export a number of API functions that enable
advanced zstd usage - C/D dictionaries, dictionaries
sharing between contexts, etc.
Cc: Nick Terrell <terrelln@fb.com>
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
include/linux/zstd.h | 167 ++++++++++++++++++++++++++++++
lib/zstd/zstd_compress_module.c | 49 +++++++++
lib/zstd/zstd_decompress_module.c | 36 +++++++
3 files changed, 252 insertions(+)
diff --git a/include/linux/zstd.h b/include/linux/zstd.h
index f109d49f43f8..ac59ae9a18d7 100644
--- a/include/linux/zstd.h
+++ b/include/linux/zstd.h
@@ -77,6 +77,30 @@ int zstd_min_clevel(void);
*/
int zstd_max_clevel(void);
+/**
+ * zstd_default_clevel() - default compression level
+ *
+ * Return: Default compression level.
+ */
+int zstd_default_clevel(void);
+
+/**
+ * struct zstd_custom_mem - custom memory allocation
+ */
+typedef ZSTD_customMem zstd_custom_mem;
+
+/**
+ * struct zstd_dict_load_method - Dictionary load method.
+ * See zstd_lib.h.
+ */
+typedef ZSTD_dictLoadMethod_e zstd_dict_load_method;
+
+/**
+ * struct zstd_dict_content_type - Dictionary context type.
+ * See zstd_lib.h.
+ */
+typedef ZSTD_dictContentType_e zstd_dict_content_type;
+
/* ====== Parameter Selection ====== */
/**
@@ -136,6 +160,19 @@ typedef ZSTD_parameters zstd_parameters;
zstd_parameters zstd_get_params(int level,
unsigned long long estimated_src_size);
+
+/**
+ * zstd_get_cparams() - returns zstd_compression_parameters for selected level
+ * @level: The compression level
+ * @estimated_src_size: The estimated source size to compress or 0
+ * if unknown.
+ * @dict_size: Dictionary size.
+ *
+ * Return: The selected zstd_compression_parameters.
+ */
+zstd_compression_parameters zstd_get_cparams(int level,
+ unsigned long long estimated_src_size, size_t dict_size);
+
/* ====== Single-pass Compression ====== */
typedef ZSTD_CCtx zstd_cctx;
@@ -180,6 +217,71 @@ zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size);
size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity,
const void *src, size_t src_size, const zstd_parameters *parameters);
+/**
+ * zstd_create_cctx_advanced() - Create compression context
+ * @custom_mem: Custom allocator.
+ *
+ * Return: NULL on error, pointer to compression context otherwise.
+ */
+zstd_cctx *zstd_create_cctx_advanced(zstd_custom_mem custom_mem);
+
+/**
+ * zstd_free_cctx() - Free compression context
+ * @cdict: Pointer to compression context.
+ *
+ * Return: Always 0.
+ */
+size_t zstd_free_cctx(zstd_cctx* cctx);
+
+/**
+ * struct zstd_cdict - Compression dictionary.
+ * See zstd_lib.h.
+ */
+typedef ZSTD_CDict zstd_cdict;
+
+/**
+ * zstd_create_cdict_byreference() - Create compression dictionary
+ * @dict: Pointer to dictionary buffer.
+ * @dict_size: Size of the dictionary buffer.
+ * @dict_load_method: Dictionary load method.
+ * @dict_content_type: Dictionary content type.
+ * @custom_mem: Memory allocator.
+ *
+ * Note, this uses @dict by reference (ZSTD_dlm_byRef), so it should be
+ * free before zstd_cdict is destroyed.
+ *
+ * Return: NULL on error, pointer to compression dictionary
+ * otherwise.
+ */
+zstd_cdict *zstd_create_cdict_byreference(const void *dict, size_t dict_size,
+ zstd_compression_parameters cparams,
+ zstd_custom_mem custom_mem);
+
+/**
+ * zstd_free_cdict() - Free compression dictionary
+ * @cdict: Pointer to compression dictionary.
+ *
+ * Return: Always 0.
+ */
+size_t zstd_free_cdict(zstd_cdict* cdict);
+
+/**
+ * zstd_compress_using_cdict() - compress src into dst using a dictionary
+ * @cctx: The context. Must have been initialized with zstd_init_cctx().
+ * @dst: The buffer to compress src into.
+ * @dst_capacity: The size of the destination buffer. May be any size, but
+ * ZSTD_compressBound(srcSize) is guaranteed to be large enough.
+ * @src: The data to compress.
+ * @src_size: The size of the data to compress.
+ * @cdict: The dictionary to be used.
+ *
+ * Return: The compressed size or an error, which can be checked using
+ * zstd_is_error().
+ */
+size_t zstd_compress_using_cdict(zstd_cctx *cctx, void *dst,
+ size_t dst_capacity, const void *src, size_t src_size,
+ const zstd_cdict *cdict);
+
/* ====== Single-pass Decompression ====== */
typedef ZSTD_DCtx zstd_dctx;
@@ -220,6 +322,71 @@ zstd_dctx *zstd_init_dctx(void *workspace, size_t workspace_size);
size_t zstd_decompress_dctx(zstd_dctx *dctx, void *dst, size_t dst_capacity,
const void *src, size_t src_size);
+/**
+ * struct zstd_ddict - Decompression dictionary.
+ * See zstd_lib.h.
+ */
+typedef ZSTD_DDict zstd_ddict;
+
+/**
+ * zstd_create_ddict_byreference() - Create decompression dictionary
+ * @dict: Pointer to dictionary buffer.
+ * @dict_size: Size of the dictionary buffer.
+ * @dict_load_method: Dictionary load method.
+ * @dict_content_type: Dictionary content type.
+ * @custom_mem: Memory allocator.
+ *
+ * Note, this uses @dict by reference (ZSTD_dlm_byRef), so it should be
+ * free before zstd_ddict is destroyed.
+ *
+ * Return: NULL on error, pointer to decompression dictionary
+ * otherwise.
+ */
+zstd_ddict *zstd_create_ddict_byreference(const void *dict, size_t dict_size,
+ zstd_custom_mem custom_mem);
+/**
+ * zstd_free_ddict() - Free decompression dictionary
+ * @dict: Pointer to the dictionary.
+ *
+ * Return: Always 0.
+ */
+size_t zstd_free_ddict(zstd_ddict *ddict);
+
+/**
+ * zstd_create_dctx_advanced() - Create decompression context
+ * @custom_mem: Custom allocator.
+ *
+ * Return: NULL on error, pointer to decompression context otherwise.
+ */
+zstd_dctx *zstd_create_dctx_advanced(zstd_custom_mem custom_mem);
+
+/**
+ * zstd_free_dctx() -- Free decompression context
+ * @dctx: Pointer to decompression context.
+ * Return: Always 0.
+ */
+size_t zstd_free_dctx(zstd_dctx *dctx);
+
+/**
+ * zstd_decompress_using_ddict() - decompress src into dst using a dictionary
+ * @dctx: The decompression context.
+ * @dst: The buffer to decompress src into.
+ * @dst_capacity: The size of the destination buffer. Must be at least as large
+ * as the decompressed size. If the caller cannot upper bound the
+ * decompressed size, then it's better to use the streaming API.
+ * @src: The zstd compressed data to decompress. Multiple concatenated
+ * frames and skippable frames are allowed.
+ * @src_size: The exact size of the data to decompress.
+ * @ddict: The dictionary to be used.
+ *
+ * Return: The decompressed size or an error, which can be checked using
+ * zstd_is_error().
+ */
+size_t zstd_decompress_using_ddict(zstd_dctx *dctx,
+ void *dst, size_t dst_capacity, const void *src, size_t src_size,
+ const zstd_ddict *ddict);
+
+
/* ====== Streaming Buffers ====== */
/**
diff --git a/lib/zstd/zstd_compress_module.c b/lib/zstd/zstd_compress_module.c
index 8ecf43226af2..ceaf352d03e2 100644
--- a/lib/zstd/zstd_compress_module.c
+++ b/lib/zstd/zstd_compress_module.c
@@ -66,6 +66,12 @@ int zstd_max_clevel(void)
}
EXPORT_SYMBOL(zstd_max_clevel);
+int zstd_default_clevel(void)
+{
+ return ZSTD_defaultCLevel();
+}
+EXPORT_SYMBOL(zstd_default_clevel);
+
size_t zstd_compress_bound(size_t src_size)
{
return ZSTD_compressBound(src_size);
@@ -79,6 +85,13 @@ zstd_parameters zstd_get_params(int level,
}
EXPORT_SYMBOL(zstd_get_params);
+zstd_compression_parameters zstd_get_cparams(int level,
+ unsigned long long estimated_src_size, size_t dict_size)
+{
+ return ZSTD_getCParams(level, estimated_src_size, dict_size);
+}
+EXPORT_SYMBOL(zstd_get_cparams);
+
size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *cparams)
{
return ZSTD_estimateCCtxSize_usingCParams(*cparams);
@@ -93,6 +106,33 @@ zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size)
}
EXPORT_SYMBOL(zstd_init_cctx);
+zstd_cctx *zstd_create_cctx_advanced(zstd_custom_mem custom_mem)
+{
+ return ZSTD_createCCtx_advanced(custom_mem);
+}
+EXPORT_SYMBOL(zstd_create_cctx_advanced);
+
+size_t zstd_free_cctx(zstd_cctx *cctx)
+{
+ return ZSTD_freeCCtx(cctx);
+}
+EXPORT_SYMBOL(zstd_free_cctx);
+
+zstd_cdict *zstd_create_cdict_byreference(const void *dict, size_t dict_size,
+ zstd_compression_parameters cparams,
+ zstd_custom_mem custom_mem)
+{
+ return ZSTD_createCDict_advanced(dict, dict_size, ZSTD_dlm_byRef,
+ ZSTD_dct_auto, cparams, custom_mem);
+}
+EXPORT_SYMBOL(zstd_create_cdict_byreference);
+
+size_t zstd_free_cdict(zstd_cdict *cdict)
+{
+ return ZSTD_freeCDict(cdict);
+}
+EXPORT_SYMBOL(zstd_free_cdict);
+
size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity,
const void *src, size_t src_size, const zstd_parameters *parameters)
{
@@ -101,6 +141,15 @@ size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity,
}
EXPORT_SYMBOL(zstd_compress_cctx);
+size_t zstd_compress_using_cdict(zstd_cctx *cctx, void *dst,
+ size_t dst_capacity, const void *src, size_t src_size,
+ const ZSTD_CDict *cdict)
+{
+ return ZSTD_compress_usingCDict(cctx, dst, dst_capacity,
+ src, src_size, cdict);
+}
+EXPORT_SYMBOL(zstd_compress_using_cdict);
+
size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams)
{
return ZSTD_estimateCStreamSize_usingCParams(*cparams);
diff --git a/lib/zstd/zstd_decompress_module.c b/lib/zstd/zstd_decompress_module.c
index 7d31518e9d5a..0ae819f0c927 100644
--- a/lib/zstd/zstd_decompress_module.c
+++ b/lib/zstd/zstd_decompress_module.c
@@ -44,6 +44,33 @@ size_t zstd_dctx_workspace_bound(void)
}
EXPORT_SYMBOL(zstd_dctx_workspace_bound);
+zstd_dctx *zstd_create_dctx_advanced(zstd_custom_mem custom_mem)
+{
+ return ZSTD_createDCtx_advanced(custom_mem);
+}
+EXPORT_SYMBOL(zstd_create_dctx_advanced);
+
+size_t zstd_free_dctx(zstd_dctx *dctx)
+{
+ return ZSTD_freeDCtx(dctx);
+}
+EXPORT_SYMBOL(zstd_free_dctx);
+
+zstd_ddict *zstd_create_ddict_byreference(const void *dict, size_t dict_size,
+ zstd_custom_mem custom_mem)
+{
+ return ZSTD_createDDict_advanced(dict, dict_size, ZSTD_dlm_byRef,
+ ZSTD_dct_auto, custom_mem);
+
+}
+EXPORT_SYMBOL(zstd_create_ddict_byreference);
+
+size_t zstd_free_ddict(zstd_ddict *ddict)
+{
+ return ZSTD_freeDDict(ddict);
+}
+EXPORT_SYMBOL(zstd_free_ddict);
+
zstd_dctx *zstd_init_dctx(void *workspace, size_t workspace_size)
{
if (workspace == NULL)
@@ -59,6 +86,15 @@ size_t zstd_decompress_dctx(zstd_dctx *dctx, void *dst, size_t dst_capacity,
}
EXPORT_SYMBOL(zstd_decompress_dctx);
+size_t zstd_decompress_using_ddict(zstd_dctx *dctx,
+ void *dst, size_t dst_capacity, const void* src, size_t src_size,
+ const zstd_ddict* ddict)
+{
+ return ZSTD_decompress_usingDDict(dctx, dst, dst_capacity, src,
+ src_size, ddict);
+}
+EXPORT_SYMBOL(zstd_decompress_using_ddict);
+
size_t zstd_dstream_workspace_bound(size_t max_window_size)
{
return ZSTD_estimateDStreamSize(max_window_size);
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 02/24] lib: lz4hc: export LZ4_resetStreamHC symbol
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 01/24] lib: zstd: export API needed for dictionary support Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 03/24] lib: zstd: fix null-deref in ZSTD_createCDict_advanced2() Sergey Senozhatsky
` (21 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky, Nick Terrell
This symbol is needed to enable lz4hc dictionary support.
Cc: Nick Terrell <terrelln@fb.com>
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
lib/lz4/lz4hc_compress.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/lz4/lz4hc_compress.c b/lib/lz4/lz4hc_compress.c
index e7ac8694b797..bc45594ad2a8 100644
--- a/lib/lz4/lz4hc_compress.c
+++ b/lib/lz4/lz4hc_compress.c
@@ -621,6 +621,7 @@ void LZ4_resetStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
LZ4_streamHCPtr->internal_donotuse.base = NULL;
LZ4_streamHCPtr->internal_donotuse.compressionLevel = (unsigned int)compressionLevel;
}
+EXPORT_SYMBOL(LZ4_resetStreamHC);
int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr,
const char *dictionary,
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 03/24] lib: zstd: fix null-deref in ZSTD_createCDict_advanced2()
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 01/24] lib: zstd: export API needed for dictionary support Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 02/24] lib: lz4hc: export LZ4_resetStreamHC symbol Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 04/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (20 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky, Nick Terrell
ZSTD_createCDict_advanced2() must ensure that
ZSTD_createCDict_advanced_internal() has successfully
allocated cdict. customMalloc() may be called under
low memory condition and may be unable to allocate
workspace for cdict.
Cc: Nick Terrell <terrelln@fb.com>
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
lib/zstd/compress/zstd_compress.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/zstd/compress/zstd_compress.c b/lib/zstd/compress/zstd_compress.c
index c1c316e9e289..e48c73880477 100644
--- a/lib/zstd/compress/zstd_compress.c
+++ b/lib/zstd/compress/zstd_compress.c
@@ -5336,6 +5336,8 @@ ZSTD_CDict* ZSTD_createCDict_advanced2(
dictLoadMethod, cctxParams.cParams,
cctxParams.useRowMatchFinder, cctxParams.enableDedicatedDictSearch,
customMem);
+ if (!cdict)
+ return NULL;
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
dict, dictSize,
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 04/24] zram: introduce custom comp backends API
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (2 preceding siblings ...)
2024-09-02 10:55 ` [PATCHv7 03/24] lib: zstd: fix null-deref in ZSTD_createCDict_advanced2() Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 05/24] zram: add lzo and lzorle compression backends support Sergey Senozhatsky
` (19 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Moving to custom backends implementation gives us ability to
have our own minimalistic and extendable API, and algorithms
tunings becomes possible.
The list of compression backends is empty at this point,
we will add backends in the followup patches.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
Documentation/admin-guide/blockdev/zram.rst | 11 +-
drivers/block/zram/Kconfig | 39 +----
drivers/block/zram/zcomp.c | 150 +++++++-------------
drivers/block/zram/zcomp.h | 29 ++--
drivers/block/zram/zram_drv.c | 9 +-
5 files changed, 78 insertions(+), 160 deletions(-)
diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst
index 091e8bb38887..181d55d64326 100644
--- a/Documentation/admin-guide/blockdev/zram.rst
+++ b/Documentation/admin-guide/blockdev/zram.rst
@@ -102,15 +102,8 @@ Examples::
#select lzo compression algorithm
echo lzo > /sys/block/zram0/comp_algorithm
-For the time being, the `comp_algorithm` content does not necessarily
-show every compression algorithm supported by the kernel. We keep this
-list primarily to simplify device configuration and one can configure
-a new device with a compression algorithm that is not listed in
-`comp_algorithm`. The thing is that, internally, ZRAM uses Crypto API
-and, if some of the algorithms were built as modules, it's impossible
-to list all of them using, for instance, /proc/crypto or any other
-method. This, however, has an advantage of permitting the usage of
-custom crypto compression modules (implementing S/W or H/W compression).
+For the time being, the `comp_algorithm` content shows only compression
+algorithms that are supported by zram.
4) Set Disksize
===============
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig
index 7b29cce60ab2..8ecb74f83a5e 100644
--- a/drivers/block/zram/Kconfig
+++ b/drivers/block/zram/Kconfig
@@ -2,7 +2,6 @@
config ZRAM
tristate "Compressed RAM block device support"
depends on BLOCK && SYSFS && MMU
- depends on CRYPTO_LZO || CRYPTO_ZSTD || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_842
select ZSMALLOC
help
Creates virtual block devices called /dev/zramX (X = 0, 1, ...).
@@ -15,45 +14,9 @@ config ZRAM
See Documentation/admin-guide/blockdev/zram.rst for more information.
-choice
- prompt "Default zram compressor"
- default ZRAM_DEF_COMP_LZORLE
- depends on ZRAM
-
-config ZRAM_DEF_COMP_LZORLE
- bool "lzo-rle"
- depends on CRYPTO_LZO
-
-config ZRAM_DEF_COMP_ZSTD
- bool "zstd"
- depends on CRYPTO_ZSTD
-
-config ZRAM_DEF_COMP_LZ4
- bool "lz4"
- depends on CRYPTO_LZ4
-
-config ZRAM_DEF_COMP_LZO
- bool "lzo"
- depends on CRYPTO_LZO
-
-config ZRAM_DEF_COMP_LZ4HC
- bool "lz4hc"
- depends on CRYPTO_LZ4HC
-
-config ZRAM_DEF_COMP_842
- bool "842"
- depends on CRYPTO_842
-
-endchoice
-
config ZRAM_DEF_COMP
string
- default "lzo-rle" if ZRAM_DEF_COMP_LZORLE
- default "zstd" if ZRAM_DEF_COMP_ZSTD
- default "lz4" if ZRAM_DEF_COMP_LZ4
- default "lzo" if ZRAM_DEF_COMP_LZO
- default "lz4hc" if ZRAM_DEF_COMP_LZ4HC
- default "842" if ZRAM_DEF_COMP_842
+ default "unset-value"
config ZRAM_WRITEBACK
bool "Write back incompressible or idle page to backing device"
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 8237b08c49d8..fa31f1b91e0f 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -1,7 +1,4 @@
// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2014 Sergey Senozhatsky.
- */
#include <linux/kernel.h>
#include <linux/string.h>
@@ -15,91 +12,68 @@
#include "zcomp.h"
-static const char * const backends[] = {
-#if IS_ENABLED(CONFIG_CRYPTO_LZO)
- "lzo",
- "lzo-rle",
-#endif
-#if IS_ENABLED(CONFIG_CRYPTO_LZ4)
- "lz4",
-#endif
-#if IS_ENABLED(CONFIG_CRYPTO_LZ4HC)
- "lz4hc",
-#endif
-#if IS_ENABLED(CONFIG_CRYPTO_842)
- "842",
-#endif
-#if IS_ENABLED(CONFIG_CRYPTO_ZSTD)
- "zstd",
-#endif
+static const struct zcomp_ops *backends[] = {
+ NULL
};
-static void zcomp_strm_free(struct zcomp_strm *zstrm)
+static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm)
{
- if (!IS_ERR_OR_NULL(zstrm->tfm))
- crypto_free_comp(zstrm->tfm);
+ if (zstrm->ctx)
+ comp->ops->destroy_ctx(zstrm->ctx);
vfree(zstrm->buffer);
- zstrm->tfm = NULL;
+ zstrm->ctx = NULL;
zstrm->buffer = NULL;
}
-/*
- * Initialize zcomp_strm structure with ->tfm initialized by backend, and
- * ->buffer. Return a negative value on error.
- */
-static int zcomp_strm_init(struct zcomp_strm *zstrm, struct zcomp *comp)
+static int zcomp_strm_init(struct zcomp *comp, struct zcomp_strm *zstrm)
{
- zstrm->tfm = crypto_alloc_comp(comp->name, 0, 0);
+ zstrm->ctx = comp->ops->create_ctx();
+
/*
* allocate 2 pages. 1 for compressed data, plus 1 extra for the
* case when compressed size is larger than the original one
*/
zstrm->buffer = vzalloc(2 * PAGE_SIZE);
- if (IS_ERR_OR_NULL(zstrm->tfm) || !zstrm->buffer) {
- zcomp_strm_free(zstrm);
+ if (!zstrm->ctx || !zstrm->buffer) {
+ zcomp_strm_free(comp, zstrm);
return -ENOMEM;
}
return 0;
}
+static const struct zcomp_ops *lookup_backend_ops(const char *comp)
+{
+ int i = 0;
+
+ while (backends[i]) {
+ if (sysfs_streq(comp, backends[i]->name))
+ break;
+ i++;
+ }
+ return backends[i];
+}
+
bool zcomp_available_algorithm(const char *comp)
{
- /*
- * Crypto does not ignore a trailing new line symbol,
- * so make sure you don't supply a string containing
- * one.
- * This also means that we permit zcomp initialisation
- * with any compressing algorithm known to crypto api.
- */
- return crypto_has_comp(comp, 0, 0) == 1;
+ return lookup_backend_ops(comp) != NULL;
}
/* show available compressors */
ssize_t zcomp_available_show(const char *comp, char *buf)
{
- bool known_algorithm = false;
ssize_t sz = 0;
int i;
- for (i = 0; i < ARRAY_SIZE(backends); i++) {
- if (!strcmp(comp, backends[i])) {
- known_algorithm = true;
+ for (i = 0; i < ARRAY_SIZE(backends) - 1; i++) {
+ if (!strcmp(comp, backends[i]->name)) {
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
- "[%s] ", backends[i]);
+ "[%s] ", backends[i]->name);
} else {
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
- "%s ", backends[i]);
+ "%s ", backends[i]->name);
}
}
- /*
- * Out-of-tree module known to crypto api or a missing
- * entry in `backends'.
- */
- if (!known_algorithm && crypto_has_comp(comp, 0, 0) == 1)
- sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
- "[%s] ", comp);
-
sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
return sz;
}
@@ -115,38 +89,25 @@ void zcomp_stream_put(struct zcomp *comp)
local_unlock(&comp->stream->lock);
}
-int zcomp_compress(struct zcomp_strm *zstrm,
- const void *src, unsigned int *dst_len)
+int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm,
+ const void *src, unsigned int *dst_len)
{
- /*
- * Our dst memory (zstrm->buffer) is always `2 * PAGE_SIZE' sized
- * because sometimes we can endup having a bigger compressed data
- * due to various reasons: for example compression algorithms tend
- * to add some padding to the compressed buffer. Speaking of padding,
- * comp algorithm `842' pads the compressed length to multiple of 8
- * and returns -ENOSP when the dst memory is not big enough, which
- * is not something that ZRAM wants to see. We can handle the
- * `compressed_size > PAGE_SIZE' case easily in ZRAM, but when we
- * receive -ERRNO from the compressing backend we can't help it
- * anymore. To make `842' happy we need to tell the exact size of
- * the dst buffer, zram_drv will take care of the fact that
- * compressed buffer is too big.
- */
- *dst_len = PAGE_SIZE * 2;
+ /* The dst buffer should always be 2 * PAGE_SIZE */
+ size_t dlen = 2 * PAGE_SIZE;
+ int ret;
- return crypto_comp_compress(zstrm->tfm,
- src, PAGE_SIZE,
- zstrm->buffer, dst_len);
+ ret = comp->ops->compress(zstrm->ctx, src, PAGE_SIZE,
+ zstrm->buffer, &dlen);
+ if (!ret)
+ *dst_len = dlen;
+ return ret;
}
-int zcomp_decompress(struct zcomp_strm *zstrm,
- const void *src, unsigned int src_len, void *dst)
+int zcomp_decompress(struct zcomp *comp, struct zcomp_strm *zstrm,
+ const void *src, unsigned int src_len, void *dst)
{
- unsigned int dst_len = PAGE_SIZE;
-
- return crypto_comp_decompress(zstrm->tfm,
- src, src_len,
- dst, &dst_len);
+ return comp->ops->decompress(zstrm->ctx, src, src_len,
+ dst, PAGE_SIZE);
}
int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node)
@@ -158,7 +119,7 @@ int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node)
zstrm = per_cpu_ptr(comp->stream, cpu);
local_lock_init(&zstrm->lock);
- ret = zcomp_strm_init(zstrm, comp);
+ ret = zcomp_strm_init(comp, zstrm);
if (ret)
pr_err("Can't allocate a compression stream\n");
return ret;
@@ -170,7 +131,7 @@ int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node)
struct zcomp_strm *zstrm;
zstrm = per_cpu_ptr(comp->stream, cpu);
- zcomp_strm_free(zstrm);
+ zcomp_strm_free(comp, zstrm);
return 0;
}
@@ -199,32 +160,21 @@ void zcomp_destroy(struct zcomp *comp)
kfree(comp);
}
-/*
- * search available compressors for requested algorithm.
- * allocate new zcomp and initialize it. return compressing
- * backend pointer or ERR_PTR if things went bad. ERR_PTR(-EINVAL)
- * if requested algorithm is not supported, ERR_PTR(-ENOMEM) in
- * case of allocation error, or any other error potentially
- * returned by zcomp_init().
- */
struct zcomp *zcomp_create(const char *alg)
{
struct zcomp *comp;
int error;
- /*
- * Crypto API will execute /sbin/modprobe if the compression module
- * is not loaded yet. We must do it here, otherwise we are about to
- * call /sbin/modprobe under CPU hot-plug lock.
- */
- if (!zcomp_available_algorithm(alg))
- return ERR_PTR(-EINVAL);
-
comp = kzalloc(sizeof(struct zcomp), GFP_KERNEL);
if (!comp)
return ERR_PTR(-ENOMEM);
- comp->name = alg;
+ comp->ops = lookup_backend_ops(alg);
+ if (!comp->ops) {
+ kfree(comp);
+ return ERR_PTR(-EINVAL);
+ }
+
error = zcomp_init(comp);
if (error) {
kfree(comp);
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
index e9fe63da0e9b..e5eb5ec4c645 100644
--- a/drivers/block/zram/zcomp.h
+++ b/drivers/block/zram/zcomp.h
@@ -1,7 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2014 Sergey Senozhatsky.
- */
#ifndef _ZCOMP_H_
#define _ZCOMP_H_
@@ -12,13 +9,26 @@ struct zcomp_strm {
local_lock_t lock;
/* compression/decompression buffer */
void *buffer;
- struct crypto_comp *tfm;
+ void *ctx;
+};
+
+struct zcomp_ops {
+ int (*compress)(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t *dst_len);
+
+ int (*decompress)(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t dst_len);
+
+ void *(*create_ctx)(void);
+ void (*destroy_ctx)(void *ctx);
+
+ const char *name;
};
/* dynamic per-device compression frontend */
struct zcomp {
struct zcomp_strm __percpu *stream;
- const char *name;
+ const struct zcomp_ops *ops;
struct hlist_node node;
};
@@ -33,10 +43,9 @@ void zcomp_destroy(struct zcomp *comp);
struct zcomp_strm *zcomp_stream_get(struct zcomp *comp);
void zcomp_stream_put(struct zcomp *comp);
-int zcomp_compress(struct zcomp_strm *zstrm,
- const void *src, unsigned int *dst_len);
-
-int zcomp_decompress(struct zcomp_strm *zstrm,
- const void *src, unsigned int src_len, void *dst);
+int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm,
+ const void *src, unsigned int *dst_len);
+int zcomp_decompress(struct zcomp *comp, struct zcomp_strm *zstrm,
+ const void *src, unsigned int src_len, void *dst);
#endif /* _ZCOMP_H_ */
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index efcb8d9d274c..93042da8ccdf 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1327,7 +1327,8 @@ static int zram_read_from_zspool(struct zram *zram, struct page *page,
ret = 0;
} else {
dst = kmap_local_page(page);
- ret = zcomp_decompress(zstrm, src, size, dst);
+ ret = zcomp_decompress(zram->comps[prio], zstrm,
+ src, size, dst);
kunmap_local(dst);
zcomp_stream_put(zram->comps[prio]);
}
@@ -1414,7 +1415,8 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index)
compress_again:
zstrm = zcomp_stream_get(zram->comps[ZRAM_PRIMARY_COMP]);
src = kmap_local_page(page);
- ret = zcomp_compress(zstrm, src, &comp_len);
+ ret = zcomp_compress(zram->comps[ZRAM_PRIMARY_COMP], zstrm,
+ src, &comp_len);
kunmap_local(src);
if (unlikely(ret)) {
@@ -1601,7 +1603,8 @@ static int zram_recompress(struct zram *zram, u32 index, struct page *page,
num_recomps++;
zstrm = zcomp_stream_get(zram->comps[prio]);
src = kmap_local_page(page);
- ret = zcomp_compress(zstrm, src, &comp_len_new);
+ ret = zcomp_compress(zram->comps[prio], zstrm,
+ src, &comp_len_new);
kunmap_local(src);
if (ret) {
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 05/24] zram: add lzo and lzorle compression backends support
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (3 preceding siblings ...)
2024-09-02 10:55 ` [PATCHv7 04/24] zram: introduce custom comp backends API Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 06/24] zram: add lz4 compression backend support Sergey Senozhatsky
` (18 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Add s/w lzo/lzorle compression support.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/Kconfig | 23 +++++++++++++++
drivers/block/zram/Makefile | 3 ++
drivers/block/zram/backend_lzo.c | 43 ++++++++++++++++++++++++++++
drivers/block/zram/backend_lzo.h | 10 +++++++
drivers/block/zram/backend_lzorle.c | 44 +++++++++++++++++++++++++++++
drivers/block/zram/backend_lzorle.h | 10 +++++++
drivers/block/zram/zcomp.c | 7 +++++
7 files changed, 140 insertions(+)
create mode 100644 drivers/block/zram/backend_lzo.c
create mode 100644 drivers/block/zram/backend_lzo.h
create mode 100644 drivers/block/zram/backend_lzorle.c
create mode 100644 drivers/block/zram/backend_lzorle.h
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig
index 8ecb74f83a5e..5d329a887b12 100644
--- a/drivers/block/zram/Kconfig
+++ b/drivers/block/zram/Kconfig
@@ -14,8 +14,31 @@ config ZRAM
See Documentation/admin-guide/blockdev/zram.rst for more information.
+config ZRAM_BACKEND_LZO
+ bool "lzo and lzo-rle compression support"
+ depends on ZRAM
+ select LZO_COMPRESS
+ select LZO_DECOMPRESS
+
+choice
+ prompt "Default zram compressor"
+ default ZRAM_DEF_COMP_LZORLE
+ depends on ZRAM
+
+config ZRAM_DEF_COMP_LZORLE
+ bool "lzo-rle"
+ depends on ZRAM_BACKEND_LZO
+
+config ZRAM_DEF_COMP_LZO
+ bool "lzo"
+ depends on ZRAM_BACKEND_LZO
+
+endchoice
+
config ZRAM_DEF_COMP
string
+ default "lzo-rle" if ZRAM_DEF_COMP_LZORLE
+ default "lzo" if ZRAM_DEF_COMP_LZO
default "unset-value"
config ZRAM_WRITEBACK
diff --git a/drivers/block/zram/Makefile b/drivers/block/zram/Makefile
index de9e457907b1..2a3db3368af9 100644
--- a/drivers/block/zram/Makefile
+++ b/drivers/block/zram/Makefile
@@ -1,4 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
+
zram-y := zcomp.o zram_drv.o
+zram-$(CONFIG_ZRAM_BACKEND_LZO) += backend_lzorle.o backend_lzo.o
+
obj-$(CONFIG_ZRAM) += zram.o
diff --git a/drivers/block/zram/backend_lzo.c b/drivers/block/zram/backend_lzo.c
new file mode 100644
index 000000000000..4c9e611f6c03
--- /dev/null
+++ b/drivers/block/zram/backend_lzo.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/lzo.h>
+
+#include "backend_lzo.h"
+
+static void *lzo_create(void)
+{
+ return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+}
+
+static void lzo_destroy(void *ctx)
+{
+ kfree(ctx);
+}
+
+static int lzo_compress(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t *dst_len)
+{
+ int ret;
+
+ ret = lzo1x_1_compress(src, src_len, dst, dst_len, ctx);
+ return ret == LZO_E_OK ? 0 : ret;
+}
+
+static int lzo_decompress(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t dst_len)
+{
+ int ret;
+
+ ret = lzo1x_decompress_safe(src, src_len, dst, &dst_len);
+ return ret == LZO_E_OK ? 0 : ret;
+}
+
+const struct zcomp_ops backend_lzo = {
+ .compress = lzo_compress,
+ .decompress = lzo_decompress,
+ .create_ctx = lzo_create,
+ .destroy_ctx = lzo_destroy,
+ .name = "lzo",
+};
diff --git a/drivers/block/zram/backend_lzo.h b/drivers/block/zram/backend_lzo.h
new file mode 100644
index 000000000000..93d54749e63c
--- /dev/null
+++ b/drivers/block/zram/backend_lzo.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef __BACKEND_LZO_H__
+#define __BACKEND_LZO_H__
+
+#include "zcomp.h"
+
+extern const struct zcomp_ops backend_lzo;
+
+#endif /* __BACKEND_LZO_H__ */
diff --git a/drivers/block/zram/backend_lzorle.c b/drivers/block/zram/backend_lzorle.c
new file mode 100644
index 000000000000..19a9ce132046
--- /dev/null
+++ b/drivers/block/zram/backend_lzorle.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/lzo.h>
+
+#include "backend_lzorle.h"
+
+static void *lzorle_create(void)
+{
+ return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+}
+
+static void lzorle_destroy(void *ctx)
+{
+ kfree(ctx);
+}
+
+static int lzorle_compress(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t *dst_len)
+{
+ int ret;
+
+ ret = lzorle1x_1_compress(src, src_len, dst, dst_len, ctx);
+ return ret == LZO_E_OK ? 0 : ret;
+}
+
+static int lzorle_decompress(void *ctx, const unsigned char *src,
+ size_t src_len, unsigned char *dst,
+ size_t dst_len)
+{
+ int ret;
+
+ ret = lzo1x_decompress_safe(src, src_len, dst, &dst_len);
+ return ret == LZO_E_OK ? 0 : ret;
+}
+
+const struct zcomp_ops backend_lzorle = {
+ .compress = lzorle_compress,
+ .decompress = lzorle_decompress,
+ .create_ctx = lzorle_create,
+ .destroy_ctx = lzorle_destroy,
+ .name = "lzo-rle",
+};
diff --git a/drivers/block/zram/backend_lzorle.h b/drivers/block/zram/backend_lzorle.h
new file mode 100644
index 000000000000..6ecb163b09f1
--- /dev/null
+++ b/drivers/block/zram/backend_lzorle.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef __BACKEND_LZORLE_H__
+#define __BACKEND_LZORLE_H__
+
+#include "zcomp.h"
+
+extern const struct zcomp_ops backend_lzorle;
+
+#endif /* __BACKEND_LZORLE_H__ */
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index fa31f1b91e0f..a49d3e355c23 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -12,7 +12,14 @@
#include "zcomp.h"
+#include "backend_lzo.h"
+#include "backend_lzorle.h"
+
static const struct zcomp_ops *backends[] = {
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZO)
+ &backend_lzorle,
+ &backend_lzo,
+#endif
NULL
};
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 06/24] zram: add lz4 compression backend support
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (4 preceding siblings ...)
2024-09-02 10:55 ` [PATCHv7 05/24] zram: add lzo and lzorle compression backends support Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 07/24] zram: add lz4hc " Sergey Senozhatsky
` (17 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Add s/w lz4 compression support.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/Kconfig | 11 +++++
drivers/block/zram/Makefile | 1 +
drivers/block/zram/backend_lz4.c | 72 ++++++++++++++++++++++++++++++++
drivers/block/zram/backend_lz4.h | 10 +++++
drivers/block/zram/zcomp.c | 4 ++
5 files changed, 98 insertions(+)
create mode 100644 drivers/block/zram/backend_lz4.c
create mode 100644 drivers/block/zram/backend_lz4.h
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig
index 5d329a887b12..f1e76fc8431a 100644
--- a/drivers/block/zram/Kconfig
+++ b/drivers/block/zram/Kconfig
@@ -20,6 +20,12 @@ config ZRAM_BACKEND_LZO
select LZO_COMPRESS
select LZO_DECOMPRESS
+config ZRAM_BACKEND_LZ4
+ bool "lz4 compression support"
+ depends on ZRAM
+ select LZ4_COMPRESS
+ select LZ4_DECOMPRESS
+
choice
prompt "Default zram compressor"
default ZRAM_DEF_COMP_LZORLE
@@ -33,12 +39,17 @@ config ZRAM_DEF_COMP_LZO
bool "lzo"
depends on ZRAM_BACKEND_LZO
+config ZRAM_DEF_COMP_LZ4
+ bool "lz4"
+ depends on ZRAM_BACKEND_LZ4
+
endchoice
config ZRAM_DEF_COMP
string
default "lzo-rle" if ZRAM_DEF_COMP_LZORLE
default "lzo" if ZRAM_DEF_COMP_LZO
+ default "lz4" if ZRAM_DEF_COMP_LZ4
default "unset-value"
config ZRAM_WRITEBACK
diff --git a/drivers/block/zram/Makefile b/drivers/block/zram/Makefile
index 2a3db3368af9..567f4434aee8 100644
--- a/drivers/block/zram/Makefile
+++ b/drivers/block/zram/Makefile
@@ -3,5 +3,6 @@
zram-y := zcomp.o zram_drv.o
zram-$(CONFIG_ZRAM_BACKEND_LZO) += backend_lzorle.o backend_lzo.o
+zram-$(CONFIG_ZRAM_BACKEND_LZ4) += backend_lz4.o
obj-$(CONFIG_ZRAM) += zram.o
diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c
new file mode 100644
index 000000000000..c1d19fed5af2
--- /dev/null
+++ b/drivers/block/zram/backend_lz4.c
@@ -0,0 +1,72 @@
+#include <linux/kernel.h>
+#include <linux/lz4.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include "backend_lz4.h"
+
+struct lz4_ctx {
+ void *mem;
+ s32 level;
+};
+
+static void lz4_destroy(void *ctx)
+{
+ struct lz4_ctx *zctx = ctx;
+
+ vfree(zctx->mem);
+ kfree(zctx);
+}
+
+static void *lz4_create(void)
+{
+ struct lz4_ctx *ctx;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return NULL;
+
+ /* @FIXME: using a hardcoded LZ4_ACCELERATION_DEFAULT for now */
+ ctx->level = LZ4_ACCELERATION_DEFAULT;
+ ctx->mem = vmalloc(LZ4_MEM_COMPRESS);
+ if (!ctx->mem)
+ goto error;
+
+ return ctx;
+error:
+ lz4_destroy(ctx);
+ return NULL;
+}
+
+static int lz4_compress(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t *dst_len)
+{
+ struct lz4_ctx *zctx = ctx;
+ int ret;
+
+ ret = LZ4_compress_fast(src, dst, src_len, *dst_len,
+ zctx->level, zctx->mem);
+ if (!ret)
+ return -EINVAL;
+ *dst_len = ret;
+ return 0;
+}
+
+static int lz4_decompress(void *ctx, const unsigned char *src,
+ size_t src_len, unsigned char *dst, size_t dst_len)
+{
+ int ret;
+
+ ret = LZ4_decompress_safe(src, dst, src_len, dst_len);
+ if (ret < 0)
+ return -EINVAL;
+ return 0;
+}
+
+const struct zcomp_ops backend_lz4 = {
+ .compress = lz4_compress,
+ .decompress = lz4_decompress,
+ .create_ctx = lz4_create,
+ .destroy_ctx = lz4_destroy,
+ .name = "lz4",
+};
diff --git a/drivers/block/zram/backend_lz4.h b/drivers/block/zram/backend_lz4.h
new file mode 100644
index 000000000000..c11fa602a703
--- /dev/null
+++ b/drivers/block/zram/backend_lz4.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef __BACKEND_LZ4_H__
+#define __BACKEND_LZ4_H__
+
+#include "zcomp.h"
+
+extern const struct zcomp_ops backend_lz4;
+
+#endif /* __BACKEND_LZ4_H__ */
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index a49d3e355c23..5da64e8fc798 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -14,11 +14,15 @@
#include "backend_lzo.h"
#include "backend_lzorle.h"
+#include "backend_lz4.h"
static const struct zcomp_ops *backends[] = {
#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZO)
&backend_lzorle,
&backend_lzo,
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZ4)
+ &backend_lz4,
#endif
NULL
};
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 07/24] zram: add lz4hc compression backend support
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (5 preceding siblings ...)
2024-09-02 10:55 ` [PATCHv7 06/24] zram: add lz4 compression backend support Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 08/24] zram: add zstd " Sergey Senozhatsky
` (16 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Add s/w lz4hc compression support.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/Kconfig | 11 +++++
drivers/block/zram/Makefile | 5 ++-
drivers/block/zram/backend_lz4hc.c | 72 ++++++++++++++++++++++++++++++
drivers/block/zram/backend_lz4hc.h | 10 +++++
drivers/block/zram/zcomp.c | 4 ++
5 files changed, 100 insertions(+), 2 deletions(-)
create mode 100644 drivers/block/zram/backend_lz4hc.c
create mode 100644 drivers/block/zram/backend_lz4hc.h
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig
index f1e76fc8431a..0d890a8d2dc4 100644
--- a/drivers/block/zram/Kconfig
+++ b/drivers/block/zram/Kconfig
@@ -26,6 +26,12 @@ config ZRAM_BACKEND_LZ4
select LZ4_COMPRESS
select LZ4_DECOMPRESS
+config ZRAM_BACKEND_LZ4HC
+ bool "lz4hc compression support"
+ depends on ZRAM
+ select LZ4HC_COMPRESS
+ select LZ4_DECOMPRESS
+
choice
prompt "Default zram compressor"
default ZRAM_DEF_COMP_LZORLE
@@ -43,6 +49,10 @@ config ZRAM_DEF_COMP_LZ4
bool "lz4"
depends on ZRAM_BACKEND_LZ4
+config ZRAM_DEF_COMP_LZ4HC
+ bool "lz4hc"
+ depends on ZRAM_BACKEND_LZ4HC
+
endchoice
config ZRAM_DEF_COMP
@@ -50,6 +60,7 @@ config ZRAM_DEF_COMP
default "lzo-rle" if ZRAM_DEF_COMP_LZORLE
default "lzo" if ZRAM_DEF_COMP_LZO
default "lz4" if ZRAM_DEF_COMP_LZ4
+ default "lz4hc" if ZRAM_DEF_COMP_LZ4HC
default "unset-value"
config ZRAM_WRITEBACK
diff --git a/drivers/block/zram/Makefile b/drivers/block/zram/Makefile
index 567f4434aee8..727c9d68e3e3 100644
--- a/drivers/block/zram/Makefile
+++ b/drivers/block/zram/Makefile
@@ -2,7 +2,8 @@
zram-y := zcomp.o zram_drv.o
-zram-$(CONFIG_ZRAM_BACKEND_LZO) += backend_lzorle.o backend_lzo.o
-zram-$(CONFIG_ZRAM_BACKEND_LZ4) += backend_lz4.o
+zram-$(CONFIG_ZRAM_BACKEND_LZO) += backend_lzorle.o backend_lzo.o
+zram-$(CONFIG_ZRAM_BACKEND_LZ4) += backend_lz4.o
+zram-$(CONFIG_ZRAM_BACKEND_LZ4HC) += backend_lz4hc.o
obj-$(CONFIG_ZRAM) += zram.o
diff --git a/drivers/block/zram/backend_lz4hc.c b/drivers/block/zram/backend_lz4hc.c
new file mode 100644
index 000000000000..536f7a0073c4
--- /dev/null
+++ b/drivers/block/zram/backend_lz4hc.c
@@ -0,0 +1,72 @@
+#include <linux/kernel.h>
+#include <linux/lz4.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include "backend_lz4hc.h"
+
+struct lz4hc_ctx {
+ void *mem;
+ s32 level;
+};
+
+static void lz4hc_destroy(void *ctx)
+{
+ struct lz4hc_ctx *zctx = ctx;
+
+ vfree(zctx->mem);
+ kfree(zctx);
+}
+
+static void *lz4hc_create(void)
+{
+ struct lz4hc_ctx *ctx;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return NULL;
+
+ /* @FIXME: using a hardcoded LZ4HC_DEFAULT_CLEVEL for now */
+ ctx->level = LZ4HC_DEFAULT_CLEVEL;
+ ctx->mem = vmalloc(LZ4HC_MEM_COMPRESS);
+ if (!ctx->mem)
+ goto error;
+
+ return ctx;
+error:
+ lz4hc_destroy(ctx);
+ return NULL;
+}
+
+static int lz4hc_compress(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t *dst_len)
+{
+ struct lz4hc_ctx *zctx = ctx;
+ int ret;
+
+ ret = LZ4_compress_HC(src, dst, src_len, *dst_len,
+ zctx->level, zctx->mem);
+ if (!ret)
+ return -EINVAL;
+ *dst_len = ret;
+ return 0;
+}
+
+static int lz4hc_decompress(void *ctx, const unsigned char *src,
+ size_t src_len, unsigned char *dst, size_t dst_len)
+{
+ int ret;
+
+ ret = LZ4_decompress_safe(src, dst, src_len, dst_len);
+ if (ret < 0)
+ return -EINVAL;
+ return 0;
+}
+
+const struct zcomp_ops backend_lz4hc = {
+ .compress = lz4hc_compress,
+ .decompress = lz4hc_decompress,
+ .create_ctx = lz4hc_create,
+ .destroy_ctx = lz4hc_destroy,
+ .name = "lz4hc",
+};
diff --git a/drivers/block/zram/backend_lz4hc.h b/drivers/block/zram/backend_lz4hc.h
new file mode 100644
index 000000000000..6de03551ed4d
--- /dev/null
+++ b/drivers/block/zram/backend_lz4hc.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef __BACKEND_LZ4HC_H__
+#define __BACKEND_LZ4HC_H__
+
+#include "zcomp.h"
+
+extern const struct zcomp_ops backend_lz4hc;
+
+#endif /* __BACKEND_LZ4HC_H__ */
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 5da64e8fc798..a06cdb9aa567 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -15,6 +15,7 @@
#include "backend_lzo.h"
#include "backend_lzorle.h"
#include "backend_lz4.h"
+#include "backend_lz4hc.h"
static const struct zcomp_ops *backends[] = {
#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZO)
@@ -23,6 +24,9 @@ static const struct zcomp_ops *backends[] = {
#endif
#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZ4)
&backend_lz4,
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZ4HC)
+ &backend_lz4hc,
#endif
NULL
};
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 08/24] zram: add zstd compression backend support
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (6 preceding siblings ...)
2024-09-02 10:55 ` [PATCHv7 07/24] zram: add lz4hc " Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 09/24] zram: pass estimated src size hint to zstd Sergey Senozhatsky
` (15 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Add s/w zstd compression.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/Kconfig | 11 ++++
drivers/block/zram/Makefile | 1 +
drivers/block/zram/backend_zstd.c | 97 +++++++++++++++++++++++++++++++
drivers/block/zram/backend_zstd.h | 10 ++++
drivers/block/zram/zcomp.c | 4 ++
5 files changed, 123 insertions(+)
create mode 100644 drivers/block/zram/backend_zstd.c
create mode 100644 drivers/block/zram/backend_zstd.h
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig
index 0d890a8d2dc4..71cd0d5d8f35 100644
--- a/drivers/block/zram/Kconfig
+++ b/drivers/block/zram/Kconfig
@@ -32,6 +32,12 @@ config ZRAM_BACKEND_LZ4HC
select LZ4HC_COMPRESS
select LZ4_DECOMPRESS
+config ZRAM_BACKEND_ZSTD
+ bool "zstd compression support"
+ depends on ZRAM
+ select ZSTD_COMPRESS
+ select ZSTD_DECOMPRESS
+
choice
prompt "Default zram compressor"
default ZRAM_DEF_COMP_LZORLE
@@ -53,6 +59,10 @@ config ZRAM_DEF_COMP_LZ4HC
bool "lz4hc"
depends on ZRAM_BACKEND_LZ4HC
+config ZRAM_DEF_COMP_ZSTD
+ bool "zstd"
+ depends on ZRAM_BACKEND_ZSTD
+
endchoice
config ZRAM_DEF_COMP
@@ -61,6 +71,7 @@ config ZRAM_DEF_COMP
default "lzo" if ZRAM_DEF_COMP_LZO
default "lz4" if ZRAM_DEF_COMP_LZ4
default "lz4hc" if ZRAM_DEF_COMP_LZ4HC
+ default "zstd" if ZRAM_DEF_COMP_ZSTD
default "unset-value"
config ZRAM_WRITEBACK
diff --git a/drivers/block/zram/Makefile b/drivers/block/zram/Makefile
index 727c9d68e3e3..a2ca227e199c 100644
--- a/drivers/block/zram/Makefile
+++ b/drivers/block/zram/Makefile
@@ -5,5 +5,6 @@ zram-y := zcomp.o zram_drv.o
zram-$(CONFIG_ZRAM_BACKEND_LZO) += backend_lzorle.o backend_lzo.o
zram-$(CONFIG_ZRAM_BACKEND_LZ4) += backend_lz4.o
zram-$(CONFIG_ZRAM_BACKEND_LZ4HC) += backend_lz4hc.o
+zram-$(CONFIG_ZRAM_BACKEND_ZSTD) += backend_zstd.o
obj-$(CONFIG_ZRAM) += zram.o
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
new file mode 100644
index 000000000000..abec68d1104b
--- /dev/null
+++ b/drivers/block/zram/backend_zstd.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/zstd.h>
+
+#include "backend_zstd.h"
+
+struct zstd_ctx {
+ zstd_cctx *cctx;
+ zstd_dctx *dctx;
+ void *cctx_mem;
+ void *dctx_mem;
+ s32 level;
+};
+
+static void zstd_destroy(void *ctx)
+{
+ struct zstd_ctx *zctx = ctx;
+
+ vfree(zctx->cctx_mem);
+ vfree(zctx->dctx_mem);
+ kfree(zctx);
+}
+
+static void *zstd_create(void)
+{
+ zstd_parameters params;
+ struct zstd_ctx *ctx;
+ size_t sz;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return NULL;
+
+ ctx->level = zstd_default_clevel();
+ params = zstd_get_params(ctx->level, 0);
+ sz = zstd_cctx_workspace_bound(¶ms.cParams);
+ ctx->cctx_mem = vzalloc(sz);
+ if (!ctx->cctx_mem)
+ goto error;
+
+ ctx->cctx = zstd_init_cctx(ctx->cctx_mem, sz);
+ if (!ctx->cctx)
+ goto error;
+
+ sz = zstd_dctx_workspace_bound();
+ ctx->dctx_mem = vzalloc(sz);
+ if (!ctx->dctx_mem)
+ goto error;
+
+ ctx->dctx = zstd_init_dctx(ctx->dctx_mem, sz);
+ if (!ctx->dctx)
+ goto error;
+
+ return ctx;
+
+error:
+ zstd_destroy(ctx);
+ return NULL;
+}
+
+static int zstd_compress(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t *dst_len)
+{
+ struct zstd_ctx *zctx = ctx;
+ const zstd_parameters params = zstd_get_params(zctx->level, 0);
+ size_t ret;
+
+ ret = zstd_compress_cctx(zctx->cctx, dst, *dst_len,
+ src, src_len, ¶ms);
+ if (zstd_is_error(ret))
+ return -EINVAL;
+ *dst_len = ret;
+ return 0;
+}
+
+static int zstd_decompress(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t dst_len)
+{
+ struct zstd_ctx *zctx = ctx;
+ size_t ret;
+
+ ret = zstd_decompress_dctx(zctx->dctx, dst, dst_len, src, src_len);
+ if (zstd_is_error(ret))
+ return -EINVAL;
+ return 0;
+}
+
+const struct zcomp_ops backend_zstd = {
+ .compress = zstd_compress,
+ .decompress = zstd_decompress,
+ .create_ctx = zstd_create,
+ .destroy_ctx = zstd_destroy,
+ .name = "zstd",
+};
diff --git a/drivers/block/zram/backend_zstd.h b/drivers/block/zram/backend_zstd.h
new file mode 100644
index 000000000000..10fdfff1ec1c
--- /dev/null
+++ b/drivers/block/zram/backend_zstd.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef __BACKEND_ZSTD_H__
+#define __BACKEND_ZSTD_H__
+
+#include "zcomp.h"
+
+extern const struct zcomp_ops backend_zstd;
+
+#endif /* __BACKEND_ZSTD_H__ */
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index a06cdb9aa567..07147659f4a2 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -16,6 +16,7 @@
#include "backend_lzorle.h"
#include "backend_lz4.h"
#include "backend_lz4hc.h"
+#include "backend_zstd.h"
static const struct zcomp_ops *backends[] = {
#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZO)
@@ -27,6 +28,9 @@ static const struct zcomp_ops *backends[] = {
#endif
#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZ4HC)
&backend_lz4hc,
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_ZSTD)
+ &backend_zstd,
#endif
NULL
};
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 09/24] zram: pass estimated src size hint to zstd
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (7 preceding siblings ...)
2024-09-02 10:55 ` [PATCHv7 08/24] zram: add zstd " Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 10/24] zram: add zlib compression backend support Sergey Senozhatsky
` (14 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
zram works with PAGE_SIZE buffers, so we always know exact
size of the source buffer and hence can pass estimated_src_size
to zstd_get_params().
This hint on x86_64, for example, reduces the size of the work
memory buffer from 1303520 bytes down to 90080 bytes. Given that
compression streams are per-CPU that's quite some memory saving.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/backend_zstd.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index abec68d1104b..310d970078e2 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -35,7 +35,7 @@ static void *zstd_create(void)
return NULL;
ctx->level = zstd_default_clevel();
- params = zstd_get_params(ctx->level, 0);
+ params = zstd_get_params(ctx->level, PAGE_SIZE);
sz = zstd_cctx_workspace_bound(¶ms.cParams);
ctx->cctx_mem = vzalloc(sz);
if (!ctx->cctx_mem)
@@ -65,7 +65,7 @@ static int zstd_compress(void *ctx, const unsigned char *src, size_t src_len,
unsigned char *dst, size_t *dst_len)
{
struct zstd_ctx *zctx = ctx;
- const zstd_parameters params = zstd_get_params(zctx->level, 0);
+ const zstd_parameters params = zstd_get_params(zctx->level, PAGE_SIZE);
size_t ret;
ret = zstd_compress_cctx(zctx->cctx, dst, *dst_len,
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 10/24] zram: add zlib compression backend support
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (8 preceding siblings ...)
2024-09-02 10:55 ` [PATCHv7 09/24] zram: pass estimated src size hint to zstd Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2025-05-08 14:19 ` Zaslonko Mikhail
2024-09-02 10:55 ` [PATCHv7 11/24] zram: add 842 " Sergey Senozhatsky
` (13 subsequent siblings)
23 siblings, 1 reply; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Add s/w zlib (inflate/deflate) compression.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/Kconfig | 11 +++
drivers/block/zram/Makefile | 1 +
drivers/block/zram/backend_deflate.c | 132 +++++++++++++++++++++++++++
drivers/block/zram/backend_deflate.h | 10 ++
drivers/block/zram/zcomp.c | 4 +
5 files changed, 158 insertions(+)
create mode 100644 drivers/block/zram/backend_deflate.c
create mode 100644 drivers/block/zram/backend_deflate.h
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig
index 71cd0d5d8f35..9dedd2edfb28 100644
--- a/drivers/block/zram/Kconfig
+++ b/drivers/block/zram/Kconfig
@@ -38,6 +38,12 @@ config ZRAM_BACKEND_ZSTD
select ZSTD_COMPRESS
select ZSTD_DECOMPRESS
+config ZRAM_BACKEND_DEFLATE
+ bool "deflate compression support"
+ depends on ZRAM
+ select ZLIB_DEFLATE
+ select ZLIB_INFLATE
+
choice
prompt "Default zram compressor"
default ZRAM_DEF_COMP_LZORLE
@@ -63,6 +69,10 @@ config ZRAM_DEF_COMP_ZSTD
bool "zstd"
depends on ZRAM_BACKEND_ZSTD
+config ZRAM_DEF_COMP_DEFLATE
+ bool "deflate"
+ depends on ZRAM_BACKEND_DEFLATE
+
endchoice
config ZRAM_DEF_COMP
@@ -72,6 +82,7 @@ config ZRAM_DEF_COMP
default "lz4" if ZRAM_DEF_COMP_LZ4
default "lz4hc" if ZRAM_DEF_COMP_LZ4HC
default "zstd" if ZRAM_DEF_COMP_ZSTD
+ default "deflate" if ZRAM_DEF_COMP_DEFLATE
default "unset-value"
config ZRAM_WRITEBACK
diff --git a/drivers/block/zram/Makefile b/drivers/block/zram/Makefile
index a2ca227e199c..266430548437 100644
--- a/drivers/block/zram/Makefile
+++ b/drivers/block/zram/Makefile
@@ -6,5 +6,6 @@ zram-$(CONFIG_ZRAM_BACKEND_LZO) += backend_lzorle.o backend_lzo.o
zram-$(CONFIG_ZRAM_BACKEND_LZ4) += backend_lz4.o
zram-$(CONFIG_ZRAM_BACKEND_LZ4HC) += backend_lz4hc.o
zram-$(CONFIG_ZRAM_BACKEND_ZSTD) += backend_zstd.o
+zram-$(CONFIG_ZRAM_BACKEND_DEFLATE) += backend_deflate.o
obj-$(CONFIG_ZRAM) += zram.o
diff --git a/drivers/block/zram/backend_deflate.c b/drivers/block/zram/backend_deflate.c
new file mode 100644
index 000000000000..acefb86701b9
--- /dev/null
+++ b/drivers/block/zram/backend_deflate.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/zlib.h>
+
+#include "backend_deflate.h"
+
+/* Use the same value as crypto API */
+#define DEFLATE_DEF_WINBITS 11
+#define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL
+
+struct deflate_ctx {
+ struct z_stream_s cctx;
+ struct z_stream_s dctx;
+ s32 level;
+};
+
+static void deflate_destroy(void *ctx)
+{
+ struct deflate_ctx *zctx = ctx;
+
+ if (zctx->cctx.workspace) {
+ zlib_deflateEnd(&zctx->cctx);
+ vfree(zctx->cctx.workspace);
+ }
+ if (zctx->dctx.workspace) {
+ zlib_inflateEnd(&zctx->dctx);
+ vfree(zctx->dctx.workspace);
+ }
+ kfree(zctx);
+}
+
+static void *deflate_create(void)
+{
+ struct deflate_ctx *ctx;
+ size_t sz;
+ int ret;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return NULL;
+
+ /* @FIXME: using a hardcoded Z_DEFAULT_COMPRESSION for now */
+ ctx->level = Z_DEFAULT_COMPRESSION;
+ sz = zlib_deflate_workspacesize(-DEFLATE_DEF_WINBITS, MAX_MEM_LEVEL);
+ ctx->cctx.workspace = vzalloc(sz);
+ if (!ctx->cctx.workspace)
+ goto error;
+
+ ret = zlib_deflateInit2(&ctx->cctx, ctx->level, Z_DEFLATED,
+ -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
+ Z_DEFAULT_STRATEGY);
+ if (ret != Z_OK)
+ goto error;
+
+ sz = zlib_inflate_workspacesize();
+ ctx->dctx.workspace = vzalloc(sz);
+ if (!ctx->dctx.workspace)
+ goto error;
+
+ ret = zlib_inflateInit2(&ctx->dctx, -DEFLATE_DEF_WINBITS);
+ if (ret != Z_OK)
+ goto error;
+
+ return ctx;
+
+error:
+ deflate_destroy(ctx);
+ return NULL;
+}
+
+static int deflate_compress(void *ctx, const unsigned char *src,
+ size_t src_len, unsigned char *dst,
+ size_t *dst_len)
+{
+ struct deflate_ctx *zctx = ctx;
+ struct z_stream_s *deflate;
+ int ret;
+
+ deflate = &zctx->cctx;
+ ret = zlib_deflateReset(deflate);
+ if (ret != Z_OK)
+ return -EINVAL;
+
+ deflate->next_in = (u8 *)src;
+ deflate->avail_in = src_len;
+ deflate->next_out = (u8 *)dst;
+ deflate->avail_out = *dst_len;
+
+ ret = zlib_deflate(deflate, Z_FINISH);
+ if (ret != Z_STREAM_END)
+ return -EINVAL;
+
+ *dst_len = deflate->total_out;
+ return 0;
+}
+
+static int deflate_decompress(void *ctx, const unsigned char *src,
+ size_t src_len, unsigned char *dst,
+ size_t dst_len)
+{
+ struct deflate_ctx *zctx = ctx;
+ struct z_stream_s *inflate;
+ int ret;
+
+ inflate = &zctx->dctx;
+
+ ret = zlib_inflateReset(inflate);
+ if (ret != Z_OK)
+ return -EINVAL;
+
+ inflate->next_in = (u8 *)src;
+ inflate->avail_in = src_len;
+ inflate->next_out = (u8 *)dst;
+ inflate->avail_out = dst_len;
+
+ ret = zlib_inflate(inflate, Z_SYNC_FLUSH);
+ if (ret != Z_STREAM_END)
+ return -EINVAL;
+
+ return 0;
+}
+
+const struct zcomp_ops backend_deflate = {
+ .compress = deflate_compress,
+ .decompress = deflate_decompress,
+ .create_ctx = deflate_create,
+ .destroy_ctx = deflate_destroy,
+ .name = "deflate",
+};
diff --git a/drivers/block/zram/backend_deflate.h b/drivers/block/zram/backend_deflate.h
new file mode 100644
index 000000000000..a39ac12b114c
--- /dev/null
+++ b/drivers/block/zram/backend_deflate.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef __BACKEND_DEFLATE_H__
+#define __BACKEND_DEFLATE_H__
+
+#include "zcomp.h"
+
+extern const struct zcomp_ops backend_deflate;
+
+#endif /* __BACKEND_DEFLATE_H__ */
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 07147659f4a2..d1396fe82b1d 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -17,6 +17,7 @@
#include "backend_lz4.h"
#include "backend_lz4hc.h"
#include "backend_zstd.h"
+#include "backend_deflate.h"
static const struct zcomp_ops *backends[] = {
#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZO)
@@ -31,6 +32,9 @@ static const struct zcomp_ops *backends[] = {
#endif
#if IS_ENABLED(CONFIG_ZRAM_BACKEND_ZSTD)
&backend_zstd,
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_DEFLATE)
+ &backend_deflate,
#endif
NULL
};
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 11/24] zram: add 842 compression backend support
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (9 preceding siblings ...)
2024-09-02 10:55 ` [PATCHv7 10/24] zram: add zlib compression backend support Sergey Senozhatsky
@ 2024-09-02 10:55 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 12/24] zram: check that backends array has at least one backend Sergey Senozhatsky
` (12 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Add s/w 842 compression support.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/Kconfig | 11 ++++++
drivers/block/zram/Makefile | 1 +
drivers/block/zram/backend_842.c | 68 ++++++++++++++++++++++++++++++++
drivers/block/zram/backend_842.h | 10 +++++
drivers/block/zram/zcomp.c | 4 ++
5 files changed, 94 insertions(+)
create mode 100644 drivers/block/zram/backend_842.c
create mode 100644 drivers/block/zram/backend_842.h
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig
index 9dedd2edfb28..1e0e7e5910b8 100644
--- a/drivers/block/zram/Kconfig
+++ b/drivers/block/zram/Kconfig
@@ -44,6 +44,12 @@ config ZRAM_BACKEND_DEFLATE
select ZLIB_DEFLATE
select ZLIB_INFLATE
+config ZRAM_BACKEND_842
+ bool "842 compression support"
+ depends on ZRAM
+ select 842_COMPRESS
+ select 842_DECOMPRESS
+
choice
prompt "Default zram compressor"
default ZRAM_DEF_COMP_LZORLE
@@ -73,6 +79,10 @@ config ZRAM_DEF_COMP_DEFLATE
bool "deflate"
depends on ZRAM_BACKEND_DEFLATE
+config ZRAM_DEF_COMP_842
+ bool "842"
+ depends on ZRAM_BACKEND_842
+
endchoice
config ZRAM_DEF_COMP
@@ -83,6 +93,7 @@ config ZRAM_DEF_COMP
default "lz4hc" if ZRAM_DEF_COMP_LZ4HC
default "zstd" if ZRAM_DEF_COMP_ZSTD
default "deflate" if ZRAM_DEF_COMP_DEFLATE
+ default "842" if ZRAM_DEF_COMP_842
default "unset-value"
config ZRAM_WRITEBACK
diff --git a/drivers/block/zram/Makefile b/drivers/block/zram/Makefile
index 266430548437..0fdefd576691 100644
--- a/drivers/block/zram/Makefile
+++ b/drivers/block/zram/Makefile
@@ -7,5 +7,6 @@ zram-$(CONFIG_ZRAM_BACKEND_LZ4) += backend_lz4.o
zram-$(CONFIG_ZRAM_BACKEND_LZ4HC) += backend_lz4hc.o
zram-$(CONFIG_ZRAM_BACKEND_ZSTD) += backend_zstd.o
zram-$(CONFIG_ZRAM_BACKEND_DEFLATE) += backend_deflate.o
+zram-$(CONFIG_ZRAM_BACKEND_842) += backend_842.o
obj-$(CONFIG_ZRAM) += zram.o
diff --git a/drivers/block/zram/backend_842.c b/drivers/block/zram/backend_842.c
new file mode 100644
index 000000000000..005f3fcb9024
--- /dev/null
+++ b/drivers/block/zram/backend_842.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sw842.h>
+#include <linux/vmalloc.h>
+
+#include "backend_842.h"
+
+struct sw842_ctx {
+ void *mem;
+};
+
+static void destroy_842(void *ctx)
+{
+ struct sw842_ctx *zctx = ctx;
+
+ kfree(zctx->mem);
+ kfree(zctx);
+}
+
+static void *create_842(void)
+{
+ struct sw842_ctx *ctx;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return NULL;
+
+ ctx->mem = kmalloc(SW842_MEM_COMPRESS, GFP_KERNEL);
+ if (!ctx->mem)
+ goto error;
+
+ return ctx;
+
+error:
+ destroy_842(ctx);
+ return NULL;
+}
+
+static int compress_842(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t *dst_len)
+{
+ struct sw842_ctx *zctx = ctx;
+ unsigned int dlen = *dst_len;
+ int ret;
+
+ ret = sw842_compress(src, src_len, dst, &dlen, zctx->mem);
+ if (ret == 0)
+ *dst_len = dlen;
+ return ret;
+}
+
+static int decompress_842(void *ctx, const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t dst_len)
+{
+ unsigned int dlen = dst_len;
+
+ return sw842_decompress(src, src_len, dst, &dlen);
+}
+
+const struct zcomp_ops backend_842 = {
+ .compress = compress_842,
+ .decompress = decompress_842,
+ .create_ctx = create_842,
+ .destroy_ctx = destroy_842,
+ .name = "842",
+};
diff --git a/drivers/block/zram/backend_842.h b/drivers/block/zram/backend_842.h
new file mode 100644
index 000000000000..4dc85c188799
--- /dev/null
+++ b/drivers/block/zram/backend_842.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef __BACKEND_842_H__
+#define __BACKEND_842_H__
+
+#include "zcomp.h"
+
+extern const struct zcomp_ops backend_842;
+
+#endif /* __BACKEND_842_H__ */
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index d1396fe82b1d..94e1c9503267 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -18,6 +18,7 @@
#include "backend_lz4hc.h"
#include "backend_zstd.h"
#include "backend_deflate.h"
+#include "backend_842.h"
static const struct zcomp_ops *backends[] = {
#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZO)
@@ -35,6 +36,9 @@ static const struct zcomp_ops *backends[] = {
#endif
#if IS_ENABLED(CONFIG_ZRAM_BACKEND_DEFLATE)
&backend_deflate,
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_842)
+ &backend_842,
#endif
NULL
};
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 12/24] zram: check that backends array has at least one backend
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (10 preceding siblings ...)
2024-09-02 10:55 ` [PATCHv7 11/24] zram: add 842 " Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 13/24] zram: introduce zcomp_params structure Sergey Senozhatsky
` (11 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Make sure that backends array has anything apart from the
sentinel NULL value.
We also select LZO_BACKEND if none backends were selected.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/Kconfig | 19 +++++++++++++------
drivers/block/zram/zcomp.c | 8 ++++++++
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig
index 1e0e7e5910b8..6aea609b795c 100644
--- a/drivers/block/zram/Kconfig
+++ b/drivers/block/zram/Kconfig
@@ -14,12 +14,6 @@ config ZRAM
See Documentation/admin-guide/blockdev/zram.rst for more information.
-config ZRAM_BACKEND_LZO
- bool "lzo and lzo-rle compression support"
- depends on ZRAM
- select LZO_COMPRESS
- select LZO_DECOMPRESS
-
config ZRAM_BACKEND_LZ4
bool "lz4 compression support"
depends on ZRAM
@@ -50,6 +44,19 @@ config ZRAM_BACKEND_842
select 842_COMPRESS
select 842_DECOMPRESS
+config ZRAM_BACKEND_FORCE_LZO
+ depends on ZRAM
+ def_bool !ZRAM_BACKEND_LZ4 && !ZRAM_BACKEND_LZ4HC && \
+ !ZRAM_BACKEND_ZSTD && !ZRAM_BACKEND_DEFLATE && \
+ !ZRAM_BACKEND_842
+
+config ZRAM_BACKEND_LZO
+ bool "lzo and lzo-rle compression support" if !ZRAM_BACKEND_FORCE_LZO
+ depends on ZRAM
+ default ZRAM_BACKEND_FORCE_LZO
+ select LZO_COMPRESS
+ select LZO_DECOMPRESS
+
choice
prompt "Default zram compressor"
default ZRAM_DEF_COMP_LZORLE
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 94e1c9503267..76d21ee77067 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -192,6 +192,14 @@ struct zcomp *zcomp_create(const char *alg)
struct zcomp *comp;
int error;
+ /*
+ * The backends array has a sentinel NULL value, so the minimum
+ * size is 1. In order to be valid the array, apart from the
+ * sentinel NULL element, should have at least one compression
+ * backend selected.
+ */
+ BUILD_BUG_ON(ARRAY_SIZE(backends) <= 1);
+
comp = kzalloc(sizeof(struct zcomp), GFP_KERNEL);
if (!comp)
return ERR_PTR(-ENOMEM);
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 13/24] zram: introduce zcomp_params structure
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (11 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 12/24] zram: check that backends array has at least one backend Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 14/24] zram: recalculate zstd compression params once Sergey Senozhatsky
` (10 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
We will store a per-algorithm parameters there (compression level,
dictionary, dictionary size, etc.).
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/backend_842.c | 2 +-
drivers/block/zram/backend_deflate.c | 9 ++++++---
drivers/block/zram/backend_lz4.c | 9 ++++++---
drivers/block/zram/backend_lz4hc.c | 9 ++++++---
drivers/block/zram/backend_lzo.c | 2 +-
drivers/block/zram/backend_lzorle.c | 2 +-
drivers/block/zram/backend_zstd.c | 18 +++++++++++-------
drivers/block/zram/zcomp.c | 5 +++--
drivers/block/zram/zcomp.h | 14 ++++++++++++--
drivers/block/zram/zram_drv.c | 20 +++++++++++++++++++-
drivers/block/zram/zram_drv.h | 1 +
11 files changed, 67 insertions(+), 24 deletions(-)
diff --git a/drivers/block/zram/backend_842.c b/drivers/block/zram/backend_842.c
index 005f3fcb9024..e14dba30b0a2 100644
--- a/drivers/block/zram/backend_842.c
+++ b/drivers/block/zram/backend_842.c
@@ -19,7 +19,7 @@ static void destroy_842(void *ctx)
kfree(zctx);
}
-static void *create_842(void)
+static void *create_842(struct zcomp_params *params)
{
struct sw842_ctx *ctx;
diff --git a/drivers/block/zram/backend_deflate.c b/drivers/block/zram/backend_deflate.c
index acefb86701b9..ec662ce46897 100644
--- a/drivers/block/zram/backend_deflate.c
+++ b/drivers/block/zram/backend_deflate.c
@@ -32,7 +32,7 @@ static void deflate_destroy(void *ctx)
kfree(zctx);
}
-static void *deflate_create(void)
+static void *deflate_create(struct zcomp_params *params)
{
struct deflate_ctx *ctx;
size_t sz;
@@ -42,8 +42,11 @@ static void *deflate_create(void)
if (!ctx)
return NULL;
- /* @FIXME: using a hardcoded Z_DEFAULT_COMPRESSION for now */
- ctx->level = Z_DEFAULT_COMPRESSION;
+ if (params->level != ZCOMP_PARAM_NO_LEVEL)
+ ctx->level = params->level;
+ else
+ ctx->level = Z_DEFAULT_COMPRESSION;
+
sz = zlib_deflate_workspacesize(-DEFLATE_DEF_WINBITS, MAX_MEM_LEVEL);
ctx->cctx.workspace = vzalloc(sz);
if (!ctx->cctx.workspace)
diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c
index c1d19fed5af2..ec57b5acbd39 100644
--- a/drivers/block/zram/backend_lz4.c
+++ b/drivers/block/zram/backend_lz4.c
@@ -18,7 +18,7 @@ static void lz4_destroy(void *ctx)
kfree(zctx);
}
-static void *lz4_create(void)
+static void *lz4_create(struct zcomp_params *params)
{
struct lz4_ctx *ctx;
@@ -26,8 +26,11 @@ static void *lz4_create(void)
if (!ctx)
return NULL;
- /* @FIXME: using a hardcoded LZ4_ACCELERATION_DEFAULT for now */
- ctx->level = LZ4_ACCELERATION_DEFAULT;
+ if (params->level != ZCOMP_PARAM_NO_LEVEL)
+ ctx->level = params->level;
+ else
+ ctx->level = LZ4_ACCELERATION_DEFAULT;
+
ctx->mem = vmalloc(LZ4_MEM_COMPRESS);
if (!ctx->mem)
goto error;
diff --git a/drivers/block/zram/backend_lz4hc.c b/drivers/block/zram/backend_lz4hc.c
index 536f7a0073c4..80733fead595 100644
--- a/drivers/block/zram/backend_lz4hc.c
+++ b/drivers/block/zram/backend_lz4hc.c
@@ -18,7 +18,7 @@ static void lz4hc_destroy(void *ctx)
kfree(zctx);
}
-static void *lz4hc_create(void)
+static void *lz4hc_create(struct zcomp_params *params)
{
struct lz4hc_ctx *ctx;
@@ -26,8 +26,11 @@ static void *lz4hc_create(void)
if (!ctx)
return NULL;
- /* @FIXME: using a hardcoded LZ4HC_DEFAULT_CLEVEL for now */
- ctx->level = LZ4HC_DEFAULT_CLEVEL;
+ if (params->level != ZCOMP_PARAM_NO_LEVEL)
+ ctx->level = params->level;
+ else
+ ctx->level = LZ4HC_DEFAULT_CLEVEL;
+
ctx->mem = vmalloc(LZ4HC_MEM_COMPRESS);
if (!ctx->mem)
goto error;
diff --git a/drivers/block/zram/backend_lzo.c b/drivers/block/zram/backend_lzo.c
index 4c9e611f6c03..8e4aabd04bf3 100644
--- a/drivers/block/zram/backend_lzo.c
+++ b/drivers/block/zram/backend_lzo.c
@@ -6,7 +6,7 @@
#include "backend_lzo.h"
-static void *lzo_create(void)
+static void *lzo_create(struct zcomp_params *params)
{
return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
}
diff --git a/drivers/block/zram/backend_lzorle.c b/drivers/block/zram/backend_lzorle.c
index 19a9ce132046..cb01eb8b04f4 100644
--- a/drivers/block/zram/backend_lzorle.c
+++ b/drivers/block/zram/backend_lzorle.c
@@ -6,7 +6,7 @@
#include "backend_lzorle.h"
-static void *lzorle_create(void)
+static void *lzorle_create(struct zcomp_params *params)
{
return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
}
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index 310d970078e2..c356c5e6e503 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -24,9 +24,9 @@ static void zstd_destroy(void *ctx)
kfree(zctx);
}
-static void *zstd_create(void)
+static void *zstd_create(struct zcomp_params *params)
{
- zstd_parameters params;
+ zstd_parameters prm;
struct zstd_ctx *ctx;
size_t sz;
@@ -34,9 +34,13 @@ static void *zstd_create(void)
if (!ctx)
return NULL;
- ctx->level = zstd_default_clevel();
- params = zstd_get_params(ctx->level, PAGE_SIZE);
- sz = zstd_cctx_workspace_bound(¶ms.cParams);
+ if (params->level != ZCOMP_PARAM_NO_LEVEL)
+ ctx->level = params->level;
+ else
+ ctx->level = zstd_default_clevel();
+
+ prm = zstd_get_params(ctx->level, PAGE_SIZE);
+ sz = zstd_cctx_workspace_bound(&prm.cParams);
ctx->cctx_mem = vzalloc(sz);
if (!ctx->cctx_mem)
goto error;
@@ -65,11 +69,11 @@ static int zstd_compress(void *ctx, const unsigned char *src, size_t src_len,
unsigned char *dst, size_t *dst_len)
{
struct zstd_ctx *zctx = ctx;
- const zstd_parameters params = zstd_get_params(zctx->level, PAGE_SIZE);
+ const zstd_parameters prm = zstd_get_params(zctx->level, PAGE_SIZE);
size_t ret;
ret = zstd_compress_cctx(zctx->cctx, dst, *dst_len,
- src, src_len, ¶ms);
+ src, src_len, &prm);
if (zstd_is_error(ret))
return -EINVAL;
*dst_len = ret;
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 76d21ee77067..173ee2b79442 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -54,7 +54,7 @@ static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm)
static int zcomp_strm_init(struct zcomp *comp, struct zcomp_strm *zstrm)
{
- zstrm->ctx = comp->ops->create_ctx();
+ zstrm->ctx = comp->ops->create_ctx(comp->params);
/*
* allocate 2 pages. 1 for compressed data, plus 1 extra for the
@@ -187,7 +187,7 @@ void zcomp_destroy(struct zcomp *comp)
kfree(comp);
}
-struct zcomp *zcomp_create(const char *alg)
+struct zcomp *zcomp_create(const char *alg, struct zcomp_params *params)
{
struct zcomp *comp;
int error;
@@ -204,6 +204,7 @@ struct zcomp *zcomp_create(const char *alg)
if (!comp)
return ERR_PTR(-ENOMEM);
+ comp->params = params;
comp->ops = lookup_backend_ops(alg);
if (!comp->ops) {
kfree(comp);
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
index e5eb5ec4c645..217a750fa908 100644
--- a/drivers/block/zram/zcomp.h
+++ b/drivers/block/zram/zcomp.h
@@ -2,8 +2,17 @@
#ifndef _ZCOMP_H_
#define _ZCOMP_H_
+
#include <linux/local_lock.h>
+#define ZCOMP_PARAM_NO_LEVEL INT_MIN
+
+struct zcomp_params {
+ void *dict;
+ size_t dict_sz;
+ s32 level;
+};
+
struct zcomp_strm {
/* The members ->buffer and ->tfm are protected by ->lock. */
local_lock_t lock;
@@ -19,7 +28,7 @@ struct zcomp_ops {
int (*decompress)(void *ctx, const unsigned char *src, size_t src_len,
unsigned char *dst, size_t dst_len);
- void *(*create_ctx)(void);
+ void *(*create_ctx)(struct zcomp_params *params);
void (*destroy_ctx)(void *ctx);
const char *name;
@@ -29,6 +38,7 @@ struct zcomp_ops {
struct zcomp {
struct zcomp_strm __percpu *stream;
const struct zcomp_ops *ops;
+ struct zcomp_params *params;
struct hlist_node node;
};
@@ -37,7 +47,7 @@ int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node);
ssize_t zcomp_available_show(const char *comp, char *buf);
bool zcomp_available_algorithm(const char *comp);
-struct zcomp *zcomp_create(const char *alg);
+struct zcomp *zcomp_create(const char *alg, struct zcomp_params *params);
void zcomp_destroy(struct zcomp *comp);
struct zcomp_strm *zcomp_stream_get(struct zcomp *comp);
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 93042da8ccdf..ff6724bbdf91 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1979,6 +1979,20 @@ static void zram_slot_free_notify(struct block_device *bdev,
zram_slot_unlock(zram, index);
}
+static void zram_comp_params_reset(struct zram *zram)
+{
+ u32 prio;
+
+ for (prio = ZRAM_PRIMARY_COMP; prio < ZRAM_MAX_COMPS; prio++) {
+ struct zcomp_params *params = &zram->params[prio];
+
+ vfree(params->dict);
+ params->level = ZCOMP_PARAM_NO_LEVEL;
+ params->dict_sz = 0;
+ params->dict = NULL;
+ }
+}
+
static void zram_destroy_comps(struct zram *zram)
{
u32 prio;
@@ -1992,6 +2006,8 @@ static void zram_destroy_comps(struct zram *zram)
zcomp_destroy(comp);
zram->num_active_comps--;
}
+
+ zram_comp_params_reset(zram);
}
static void zram_reset_device(struct zram *zram)
@@ -2049,7 +2065,8 @@ static ssize_t disksize_store(struct device *dev,
if (!zram->comp_algs[prio])
continue;
- comp = zcomp_create(zram->comp_algs[prio]);
+ comp = zcomp_create(zram->comp_algs[prio],
+ &zram->params[prio]);
if (IS_ERR(comp)) {
pr_err("Cannot initialise %s compressing backend\n",
zram->comp_algs[prio]);
@@ -2254,6 +2271,7 @@ static int zram_add(void)
if (ret)
goto out_cleanup_disk;
+ zram_comp_params_reset(zram);
comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor);
zram_debugfs_register(zram);
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 35e322144629..b976824ead67 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -107,6 +107,7 @@ struct zram {
struct zram_table_entry *table;
struct zs_pool *mem_pool;
struct zcomp *comps[ZRAM_MAX_COMPS];
+ struct zcomp_params params[ZRAM_MAX_COMPS];
struct gendisk *disk;
/* Prevent concurrent execution of device init */
struct rw_semaphore init_lock;
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 14/24] zram: recalculate zstd compression params once
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (12 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 13/24] zram: introduce zcomp_params structure Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 15/24] zram: introduce algorithm_params device attribute Sergey Senozhatsky
` (9 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
zstd compression params depends on level, but are constant
for a given instance of zstd compression backend. Calculate
once (during ctx creation).
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/backend_zstd.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index c356c5e6e503..7c6798f0c912 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -10,6 +10,7 @@
struct zstd_ctx {
zstd_cctx *cctx;
zstd_dctx *dctx;
+ zstd_parameters cprm;
void *cctx_mem;
void *dctx_mem;
s32 level;
@@ -40,6 +41,7 @@ static void *zstd_create(struct zcomp_params *params)
ctx->level = zstd_default_clevel();
prm = zstd_get_params(ctx->level, PAGE_SIZE);
+ ctx->cprm = zstd_get_params(ctx->level, PAGE_SIZE);
sz = zstd_cctx_workspace_bound(&prm.cParams);
ctx->cctx_mem = vzalloc(sz);
if (!ctx->cctx_mem)
@@ -69,11 +71,10 @@ static int zstd_compress(void *ctx, const unsigned char *src, size_t src_len,
unsigned char *dst, size_t *dst_len)
{
struct zstd_ctx *zctx = ctx;
- const zstd_parameters prm = zstd_get_params(zctx->level, PAGE_SIZE);
size_t ret;
ret = zstd_compress_cctx(zctx->cctx, dst, *dst_len,
- src, src_len, &prm);
+ src, src_len, &zctx->cprm);
if (zstd_is_error(ret))
return -EINVAL;
*dst_len = ret;
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 15/24] zram: introduce algorithm_params device attribute
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (13 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 14/24] zram: recalculate zstd compression params once Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 16/24] zram: add support for dict comp config Sergey Senozhatsky
` (8 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
This attribute is used to setup compression algorithms'
parameters, so we can tweak algorithms' characteristics.
At this point only 'level' is supported (to be extended
in the future).
Each call sets up parameters for one particular algorithm,
which should be specified either by the algorithm's priority
or algo name. This is expected to be called after corresponding
algorithm is selected via comp_algorithm or recomp_algorithm.
echo "priority=0 level=1" > /sys/block/zram0/algorithm_params
or
echo "algo=zstd level=1" > /sys/block/zram0/algorithm_params
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
Documentation/ABI/testing/sysfs-block-zram | 7 +++
Documentation/admin-guide/blockdev/zram.rst | 1 +
drivers/block/zram/zram_drv.c | 68 +++++++++++++++++++++
3 files changed, 76 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-block-zram b/Documentation/ABI/testing/sysfs-block-zram
index 628a00fb20a9..1ef69e0271f9 100644
--- a/Documentation/ABI/testing/sysfs-block-zram
+++ b/Documentation/ABI/testing/sysfs-block-zram
@@ -151,3 +151,10 @@ Contact: Sergey Senozhatsky <senozhatsky@chromium.org>
Description:
The recompress file is write-only and triggers re-compression
with secondary compression algorithms.
+
+What: /sys/block/zram<id>/algorithm_params
+Date: August 2024
+Contact: Sergey Senozhatsky <senozhatsky@chromium.org>
+Description:
+ The algorithm_params file is write-only and is used to setup
+ compression algorithm parameters.
diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst
index 181d55d64326..96d81dc12528 100644
--- a/Documentation/admin-guide/blockdev/zram.rst
+++ b/Documentation/admin-guide/blockdev/zram.rst
@@ -198,6 +198,7 @@ writeback_limit_enable RW show and set writeback_limit feature
max_comp_streams RW the number of possible concurrent compress
operations
comp_algorithm RW show and change the compression algorithm
+algorithm_params WO setup compression algorithm parameters
compact WO trigger memory compaction
debug_stat RO this file is used for zram debugging purposes
backing_dev RW set up backend storage for zram to write out
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index ff6724bbdf91..e29e952b99c3 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -998,6 +998,72 @@ static int __comp_algorithm_store(struct zram *zram, u32 prio, const char *buf)
return 0;
}
+static int comp_params_store(struct zram *zram, u32 prio, s32 level)
+{
+ zram->params[prio].level = level;
+ return 0;
+}
+
+static ssize_t algorithm_params_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
+{
+ s32 prio = ZRAM_PRIMARY_COMP, level = ZCOMP_PARAM_NO_LEVEL;
+ char *args, *param, *val, *algo = NULL;
+ struct zram *zram = dev_to_zram(dev);
+ int ret;
+
+ args = skip_spaces(buf);
+ while (*args) {
+ args = next_arg(args, ¶m, &val);
+
+ if (!val || !*val)
+ return -EINVAL;
+
+ if (!strcmp(param, "priority")) {
+ ret = kstrtoint(val, 10, &prio);
+ if (ret)
+ return ret;
+ continue;
+ }
+
+ if (!strcmp(param, "level")) {
+ ret = kstrtoint(val, 10, &level);
+ if (ret)
+ return ret;
+ continue;
+ }
+
+ if (!strcmp(param, "algo")) {
+ algo = val;
+ continue;
+ }
+ }
+
+ /* Lookup priority by algorithm name */
+ if (algo) {
+ s32 p;
+
+ prio = -EINVAL;
+ for (p = ZRAM_PRIMARY_COMP; p < ZRAM_MAX_COMPS; p++) {
+ if (!zram->comp_algs[p])
+ continue;
+
+ if (!strcmp(zram->comp_algs[p], algo)) {
+ prio = p;
+ break;
+ }
+ }
+ }
+
+ if (prio < ZRAM_PRIMARY_COMP || prio >= ZRAM_MAX_COMPS)
+ return -EINVAL;
+
+ ret = comp_params_store(zram, prio, level);
+ return ret ? ret : len;
+}
+
static ssize_t comp_algorithm_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -2169,6 +2235,7 @@ static DEVICE_ATTR_RW(writeback_limit_enable);
static DEVICE_ATTR_RW(recomp_algorithm);
static DEVICE_ATTR_WO(recompress);
#endif
+static DEVICE_ATTR_WO(algorithm_params);
static struct attribute *zram_disk_attrs[] = {
&dev_attr_disksize.attr,
@@ -2196,6 +2263,7 @@ static struct attribute *zram_disk_attrs[] = {
&dev_attr_recomp_algorithm.attr,
&dev_attr_recompress.attr,
#endif
+ &dev_attr_algorithm_params.attr,
NULL,
};
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 16/24] zram: add support for dict comp config
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (14 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 15/24] zram: introduce algorithm_params device attribute Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 17/24] zram: introduce zcomp_req structure Sergey Senozhatsky
` (7 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Handle dict=path algorithm param so that we can read a
pre-trained compression algorithm dictionary which we
then pass to the backend configuration.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/zram_drv.c | 45 ++++++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 9 deletions(-)
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index e29e952b99c3..9b29f9e6cb50 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -33,6 +33,7 @@
#include <linux/debugfs.h>
#include <linux/cpuhotplug.h>
#include <linux/part_stat.h>
+#include <linux/kernel_read_file.h>
#include "zram_drv.h"
@@ -998,8 +999,34 @@ static int __comp_algorithm_store(struct zram *zram, u32 prio, const char *buf)
return 0;
}
-static int comp_params_store(struct zram *zram, u32 prio, s32 level)
+static void comp_params_reset(struct zram *zram, u32 prio)
{
+ struct zcomp_params *params = &zram->params[prio];
+
+ vfree(params->dict);
+ params->level = ZCOMP_PARAM_NO_LEVEL;
+ params->dict_sz = 0;
+ params->dict = NULL;
+}
+
+static int comp_params_store(struct zram *zram, u32 prio, s32 level,
+ const char *dict_path)
+{
+ ssize_t sz = 0;
+
+ comp_params_reset(zram, prio);
+
+ if (dict_path) {
+ sz = kernel_read_file_from_path(dict_path, 0,
+ &zram->params[prio].dict,
+ INT_MAX,
+ NULL,
+ READING_POLICY);
+ if (sz < 0)
+ return -EINVAL;
+ }
+
+ zram->params[prio].dict_sz = sz;
zram->params[prio].level = level;
return 0;
}
@@ -1010,7 +1037,7 @@ static ssize_t algorithm_params_store(struct device *dev,
size_t len)
{
s32 prio = ZRAM_PRIMARY_COMP, level = ZCOMP_PARAM_NO_LEVEL;
- char *args, *param, *val, *algo = NULL;
+ char *args, *param, *val, *algo = NULL, *dict_path = NULL;
struct zram *zram = dev_to_zram(dev);
int ret;
@@ -1039,6 +1066,11 @@ static ssize_t algorithm_params_store(struct device *dev,
algo = val;
continue;
}
+
+ if (!strcmp(param, "dict")) {
+ dict_path = val;
+ continue;
+ }
}
/* Lookup priority by algorithm name */
@@ -1060,7 +1092,7 @@ static ssize_t algorithm_params_store(struct device *dev,
if (prio < ZRAM_PRIMARY_COMP || prio >= ZRAM_MAX_COMPS)
return -EINVAL;
- ret = comp_params_store(zram, prio, level);
+ ret = comp_params_store(zram, prio, level, dict_path);
return ret ? ret : len;
}
@@ -2050,12 +2082,7 @@ static void zram_comp_params_reset(struct zram *zram)
u32 prio;
for (prio = ZRAM_PRIMARY_COMP; prio < ZRAM_MAX_COMPS; prio++) {
- struct zcomp_params *params = &zram->params[prio];
-
- vfree(params->dict);
- params->level = ZCOMP_PARAM_NO_LEVEL;
- params->dict_sz = 0;
- params->dict = NULL;
+ comp_params_reset(zram, prio);
}
}
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 17/24] zram: introduce zcomp_req structure
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (15 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 16/24] zram: add support for dict comp config Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 18/24] zram: introduce zcomp_ctx structure Sergey Senozhatsky
` (6 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Encapsulate compression/decompression data in zcomp_req
structure.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/backend_842.c | 17 ++++++++---------
drivers/block/zram/backend_deflate.c | 26 +++++++++++---------------
drivers/block/zram/backend_lz4.c | 15 +++++++--------
drivers/block/zram/backend_lz4hc.c | 13 ++++++-------
drivers/block/zram/backend_lzo.c | 12 ++++++------
drivers/block/zram/backend_lzorle.c | 13 ++++++-------
drivers/block/zram/backend_zstd.c | 15 +++++++--------
drivers/block/zram/zcomp.c | 23 ++++++++++++++++-------
drivers/block/zram/zcomp.h | 15 ++++++++++-----
9 files changed, 77 insertions(+), 72 deletions(-)
diff --git a/drivers/block/zram/backend_842.c b/drivers/block/zram/backend_842.c
index e14dba30b0a2..1597dc4d4f1c 100644
--- a/drivers/block/zram/backend_842.c
+++ b/drivers/block/zram/backend_842.c
@@ -38,25 +38,24 @@ static void *create_842(struct zcomp_params *params)
return NULL;
}
-static int compress_842(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t *dst_len)
+static int compress_842(void *ctx, struct zcomp_req *req)
{
struct sw842_ctx *zctx = ctx;
- unsigned int dlen = *dst_len;
+ unsigned int dlen = req->dst_len;
int ret;
- ret = sw842_compress(src, src_len, dst, &dlen, zctx->mem);
+ ret = sw842_compress(req->src, req->src_len, req->dst, &dlen,
+ zctx->mem);
if (ret == 0)
- *dst_len = dlen;
+ req->dst_len = dlen;
return ret;
}
-static int decompress_842(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t dst_len)
+static int decompress_842(void *ctx, struct zcomp_req *req)
{
- unsigned int dlen = dst_len;
+ unsigned int dlen = req->dst_len;
- return sw842_decompress(src, src_len, dst, &dlen);
+ return sw842_decompress(req->src, req->src_len, req->dst, &dlen);
}
const struct zcomp_ops backend_842 = {
diff --git a/drivers/block/zram/backend_deflate.c b/drivers/block/zram/backend_deflate.c
index ec662ce46897..117852d45aa4 100644
--- a/drivers/block/zram/backend_deflate.c
+++ b/drivers/block/zram/backend_deflate.c
@@ -74,9 +74,7 @@ static void *deflate_create(struct zcomp_params *params)
return NULL;
}
-static int deflate_compress(void *ctx, const unsigned char *src,
- size_t src_len, unsigned char *dst,
- size_t *dst_len)
+static int deflate_compress(void *ctx, struct zcomp_req *req)
{
struct deflate_ctx *zctx = ctx;
struct z_stream_s *deflate;
@@ -87,22 +85,20 @@ static int deflate_compress(void *ctx, const unsigned char *src,
if (ret != Z_OK)
return -EINVAL;
- deflate->next_in = (u8 *)src;
- deflate->avail_in = src_len;
- deflate->next_out = (u8 *)dst;
- deflate->avail_out = *dst_len;
+ deflate->next_in = (u8 *)req->src;
+ deflate->avail_in = req->src_len;
+ deflate->next_out = (u8 *)req->dst;
+ deflate->avail_out = req->dst_len;
ret = zlib_deflate(deflate, Z_FINISH);
if (ret != Z_STREAM_END)
return -EINVAL;
- *dst_len = deflate->total_out;
+ req->dst_len = deflate->total_out;
return 0;
}
-static int deflate_decompress(void *ctx, const unsigned char *src,
- size_t src_len, unsigned char *dst,
- size_t dst_len)
+static int deflate_decompress(void *ctx, struct zcomp_req *req)
{
struct deflate_ctx *zctx = ctx;
struct z_stream_s *inflate;
@@ -114,10 +110,10 @@ static int deflate_decompress(void *ctx, const unsigned char *src,
if (ret != Z_OK)
return -EINVAL;
- inflate->next_in = (u8 *)src;
- inflate->avail_in = src_len;
- inflate->next_out = (u8 *)dst;
- inflate->avail_out = dst_len;
+ inflate->next_in = (u8 *)req->src;
+ inflate->avail_in = req->src_len;
+ inflate->next_out = (u8 *)req->dst;
+ inflate->avail_out = req->dst_len;
ret = zlib_inflate(inflate, Z_SYNC_FLUSH);
if (ret != Z_STREAM_END)
diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c
index ec57b5acbd39..cc4ae4097870 100644
--- a/drivers/block/zram/backend_lz4.c
+++ b/drivers/block/zram/backend_lz4.c
@@ -41,26 +41,25 @@ static void *lz4_create(struct zcomp_params *params)
return NULL;
}
-static int lz4_compress(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t *dst_len)
+static int lz4_compress(void *ctx, struct zcomp_req *req)
{
struct lz4_ctx *zctx = ctx;
int ret;
- ret = LZ4_compress_fast(src, dst, src_len, *dst_len,
- zctx->level, zctx->mem);
+ ret = LZ4_compress_fast(req->src, req->dst, req->src_len,
+ req->dst_len, zctx->level, zctx->mem);
if (!ret)
return -EINVAL;
- *dst_len = ret;
+ req->dst_len = ret;
return 0;
}
-static int lz4_decompress(void *ctx, const unsigned char *src,
- size_t src_len, unsigned char *dst, size_t dst_len)
+static int lz4_decompress(void *ctx, struct zcomp_req *req)
{
int ret;
- ret = LZ4_decompress_safe(src, dst, src_len, dst_len);
+ ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
+ req->dst_len);
if (ret < 0)
return -EINVAL;
return 0;
diff --git a/drivers/block/zram/backend_lz4hc.c b/drivers/block/zram/backend_lz4hc.c
index 80733fead595..610dadc09751 100644
--- a/drivers/block/zram/backend_lz4hc.c
+++ b/drivers/block/zram/backend_lz4hc.c
@@ -41,26 +41,25 @@ static void *lz4hc_create(struct zcomp_params *params)
return NULL;
}
-static int lz4hc_compress(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t *dst_len)
+static int lz4hc_compress(void *ctx, struct zcomp_req *req)
{
struct lz4hc_ctx *zctx = ctx;
int ret;
- ret = LZ4_compress_HC(src, dst, src_len, *dst_len,
+ ret = LZ4_compress_HC(req->src, req->dst, req->src_len, req->dst_len,
zctx->level, zctx->mem);
if (!ret)
return -EINVAL;
- *dst_len = ret;
+ req->dst_len = ret;
return 0;
}
-static int lz4hc_decompress(void *ctx, const unsigned char *src,
- size_t src_len, unsigned char *dst, size_t dst_len)
+static int lz4hc_decompress(void *ctx, struct zcomp_req *req)
{
int ret;
- ret = LZ4_decompress_safe(src, dst, src_len, dst_len);
+ ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
+ req->dst_len);
if (ret < 0)
return -EINVAL;
return 0;
diff --git a/drivers/block/zram/backend_lzo.c b/drivers/block/zram/backend_lzo.c
index 8e4aabd04bf3..88f1aa5683f3 100644
--- a/drivers/block/zram/backend_lzo.c
+++ b/drivers/block/zram/backend_lzo.c
@@ -16,21 +16,21 @@ static void lzo_destroy(void *ctx)
kfree(ctx);
}
-static int lzo_compress(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t *dst_len)
+static int lzo_compress(void *ctx, struct zcomp_req *req)
{
int ret;
- ret = lzo1x_1_compress(src, src_len, dst, dst_len, ctx);
+ ret = lzo1x_1_compress(req->src, req->src_len, req->dst,
+ &req->dst_len, ctx);
return ret == LZO_E_OK ? 0 : ret;
}
-static int lzo_decompress(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t dst_len)
+static int lzo_decompress(void *ctx, struct zcomp_req *req)
{
int ret;
- ret = lzo1x_decompress_safe(src, src_len, dst, &dst_len);
+ ret = lzo1x_decompress_safe(req->src, req->src_len,
+ req->dst, &req->dst_len);
return ret == LZO_E_OK ? 0 : ret;
}
diff --git a/drivers/block/zram/backend_lzorle.c b/drivers/block/zram/backend_lzorle.c
index cb01eb8b04f4..f05820929a74 100644
--- a/drivers/block/zram/backend_lzorle.c
+++ b/drivers/block/zram/backend_lzorle.c
@@ -16,22 +16,21 @@ static void lzorle_destroy(void *ctx)
kfree(ctx);
}
-static int lzorle_compress(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t *dst_len)
+static int lzorle_compress(void *ctx, struct zcomp_req *req)
{
int ret;
- ret = lzorle1x_1_compress(src, src_len, dst, dst_len, ctx);
+ ret = lzorle1x_1_compress(req->src, req->src_len, req->dst,
+ &req->dst_len, ctx);
return ret == LZO_E_OK ? 0 : ret;
}
-static int lzorle_decompress(void *ctx, const unsigned char *src,
- size_t src_len, unsigned char *dst,
- size_t dst_len)
+static int lzorle_decompress(void *ctx, struct zcomp_req *req)
{
int ret;
- ret = lzo1x_decompress_safe(src, src_len, dst, &dst_len);
+ ret = lzo1x_decompress_safe(req->src, req->src_len,
+ req->dst, &req->dst_len);
return ret == LZO_E_OK ? 0 : ret;
}
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index 7c6798f0c912..19eba65f44c9 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -67,27 +67,26 @@ static void *zstd_create(struct zcomp_params *params)
return NULL;
}
-static int zstd_compress(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t *dst_len)
+static int zstd_compress(void *ctx, struct zcomp_req *req)
{
struct zstd_ctx *zctx = ctx;
size_t ret;
- ret = zstd_compress_cctx(zctx->cctx, dst, *dst_len,
- src, src_len, &zctx->cprm);
+ ret = zstd_compress_cctx(zctx->cctx, req->dst, req->dst_len,
+ req->src, req->src_len, &zctx->cprm);
if (zstd_is_error(ret))
return -EINVAL;
- *dst_len = ret;
+ req->dst_len = ret;
return 0;
}
-static int zstd_decompress(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t dst_len)
+static int zstd_decompress(void *ctx, struct zcomp_req *req)
{
struct zstd_ctx *zctx = ctx;
size_t ret;
- ret = zstd_decompress_dctx(zctx->dctx, dst, dst_len, src, src_len);
+ ret = zstd_decompress_dctx(zctx->dctx, req->dst, req->dst_len,
+ req->src, req->src_len);
if (zstd_is_error(ret))
return -EINVAL;
return 0;
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 173ee2b79442..20ad7b6fe62f 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -119,22 +119,31 @@ void zcomp_stream_put(struct zcomp *comp)
int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm,
const void *src, unsigned int *dst_len)
{
- /* The dst buffer should always be 2 * PAGE_SIZE */
- size_t dlen = 2 * PAGE_SIZE;
+ struct zcomp_req req = {
+ .src = src,
+ .dst = zstrm->buffer,
+ .src_len = PAGE_SIZE,
+ .dst_len = 2 * PAGE_SIZE,
+ };
int ret;
- ret = comp->ops->compress(zstrm->ctx, src, PAGE_SIZE,
- zstrm->buffer, &dlen);
+ ret = comp->ops->compress(zstrm->ctx, &req);
if (!ret)
- *dst_len = dlen;
+ *dst_len = req.dst_len;
return ret;
}
int zcomp_decompress(struct zcomp *comp, struct zcomp_strm *zstrm,
const void *src, unsigned int src_len, void *dst)
{
- return comp->ops->decompress(zstrm->ctx, src, src_len,
- dst, PAGE_SIZE);
+ struct zcomp_req req = {
+ .src = src,
+ .dst = dst,
+ .src_len = src_len,
+ .dst_len = PAGE_SIZE,
+ };
+
+ return comp->ops->decompress(zstrm->ctx, &req);
}
int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node)
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
index 217a750fa908..bbc48094f826 100644
--- a/drivers/block/zram/zcomp.h
+++ b/drivers/block/zram/zcomp.h
@@ -21,12 +21,17 @@ struct zcomp_strm {
void *ctx;
};
-struct zcomp_ops {
- int (*compress)(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t *dst_len);
+struct zcomp_req {
+ const unsigned char *src;
+ const size_t src_len;
+
+ unsigned char *dst;
+ size_t dst_len;
+};
- int (*decompress)(void *ctx, const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t dst_len);
+struct zcomp_ops {
+ int (*compress)(void *ctx, struct zcomp_req *req);
+ int (*decompress)(void *ctx, struct zcomp_req *req);
void *(*create_ctx)(struct zcomp_params *params);
void (*destroy_ctx)(void *ctx);
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 18/24] zram: introduce zcomp_ctx structure
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (16 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 17/24] zram: introduce zcomp_req structure Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 19/24] zram: move immutable comp params away from per-CPU context Sergey Senozhatsky
` (5 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Keep run-time driver data (scratch buffers, etc.) in
zcomp_ctx structure. This structure is allocated per-CPU
because drivers (backends) need to modify its content
during requests execution.
We will split mutable and immutable driver data, this is
a preparation path.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/backend_842.c | 39 ++++++--------------
drivers/block/zram/backend_deflate.c | 46 +++++++++++++-----------
drivers/block/zram/backend_lz4.c | 36 ++++++++++---------
drivers/block/zram/backend_lz4hc.c | 36 ++++++++++---------
drivers/block/zram/backend_lzo.c | 17 +++++----
drivers/block/zram/backend_lzorle.c | 17 +++++----
drivers/block/zram/backend_zstd.c | 54 +++++++++++++++-------------
drivers/block/zram/zcomp.c | 16 +++++----
drivers/block/zram/zcomp.h | 23 ++++++++----
9 files changed, 149 insertions(+), 135 deletions(-)
diff --git a/drivers/block/zram/backend_842.c b/drivers/block/zram/backend_842.c
index 1597dc4d4f1c..2f1202322264 100644
--- a/drivers/block/zram/backend_842.c
+++ b/drivers/block/zram/backend_842.c
@@ -7,51 +7,32 @@
#include "backend_842.h"
-struct sw842_ctx {
- void *mem;
-};
-
-static void destroy_842(void *ctx)
+static void destroy_842(struct zcomp_ctx *ctx)
{
- struct sw842_ctx *zctx = ctx;
-
- kfree(zctx->mem);
- kfree(zctx);
+ kfree(ctx->context);
}
-static void *create_842(struct zcomp_params *params)
+static int create_842(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- struct sw842_ctx *ctx;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return NULL;
-
- ctx->mem = kmalloc(SW842_MEM_COMPRESS, GFP_KERNEL);
- if (!ctx->mem)
- goto error;
-
- return ctx;
-
-error:
- destroy_842(ctx);
- return NULL;
+ ctx->context = kmalloc(SW842_MEM_COMPRESS, GFP_KERNEL);
+ if (!ctx->context)
+ return -ENOMEM;
+ return 0;
}
-static int compress_842(void *ctx, struct zcomp_req *req)
+static int compress_842(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
- struct sw842_ctx *zctx = ctx;
unsigned int dlen = req->dst_len;
int ret;
ret = sw842_compress(req->src, req->src_len, req->dst, &dlen,
- zctx->mem);
+ ctx->context);
if (ret == 0)
req->dst_len = dlen;
return ret;
}
-static int decompress_842(void *ctx, struct zcomp_req *req)
+static int decompress_842(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
unsigned int dlen = req->dst_len;
diff --git a/drivers/block/zram/backend_deflate.c b/drivers/block/zram/backend_deflate.c
index 117852d45aa4..eae4ee35c1df 100644
--- a/drivers/block/zram/backend_deflate.c
+++ b/drivers/block/zram/backend_deflate.c
@@ -17,9 +17,12 @@ struct deflate_ctx {
s32 level;
};
-static void deflate_destroy(void *ctx)
+static void deflate_destroy(struct zcomp_ctx *ctx)
{
- struct deflate_ctx *zctx = ctx;
+ struct deflate_ctx *zctx = ctx->context;
+
+ if (!zctx)
+ return;
if (zctx->cctx.workspace) {
zlib_deflateEnd(&zctx->cctx);
@@ -32,51 +35,52 @@ static void deflate_destroy(void *ctx)
kfree(zctx);
}
-static void *deflate_create(struct zcomp_params *params)
+static int deflate_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- struct deflate_ctx *ctx;
+ struct deflate_ctx *zctx;
size_t sz;
int ret;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return NULL;
+ zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
+ if (!zctx)
+ return -ENOMEM;
+ ctx->context = zctx;
if (params->level != ZCOMP_PARAM_NO_LEVEL)
- ctx->level = params->level;
+ zctx->level = params->level;
else
- ctx->level = Z_DEFAULT_COMPRESSION;
+ zctx->level = Z_DEFAULT_COMPRESSION;
sz = zlib_deflate_workspacesize(-DEFLATE_DEF_WINBITS, MAX_MEM_LEVEL);
- ctx->cctx.workspace = vzalloc(sz);
- if (!ctx->cctx.workspace)
+ zctx->cctx.workspace = vzalloc(sz);
+ if (!zctx->cctx.workspace)
goto error;
- ret = zlib_deflateInit2(&ctx->cctx, ctx->level, Z_DEFLATED,
+ ret = zlib_deflateInit2(&zctx->cctx, zctx->level, Z_DEFLATED,
-DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
Z_DEFAULT_STRATEGY);
if (ret != Z_OK)
goto error;
sz = zlib_inflate_workspacesize();
- ctx->dctx.workspace = vzalloc(sz);
- if (!ctx->dctx.workspace)
+ zctx->dctx.workspace = vzalloc(sz);
+ if (!zctx->dctx.workspace)
goto error;
- ret = zlib_inflateInit2(&ctx->dctx, -DEFLATE_DEF_WINBITS);
+ ret = zlib_inflateInit2(&zctx->dctx, -DEFLATE_DEF_WINBITS);
if (ret != Z_OK)
goto error;
- return ctx;
+ return 0;
error:
deflate_destroy(ctx);
- return NULL;
+ return -EINVAL;
}
-static int deflate_compress(void *ctx, struct zcomp_req *req)
+static int deflate_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
- struct deflate_ctx *zctx = ctx;
+ struct deflate_ctx *zctx = ctx->context;
struct z_stream_s *deflate;
int ret;
@@ -98,9 +102,9 @@ static int deflate_compress(void *ctx, struct zcomp_req *req)
return 0;
}
-static int deflate_decompress(void *ctx, struct zcomp_req *req)
+static int deflate_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
- struct deflate_ctx *zctx = ctx;
+ struct deflate_ctx *zctx = ctx->context;
struct z_stream_s *inflate;
int ret;
diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c
index cc4ae4097870..e2d951e62746 100644
--- a/drivers/block/zram/backend_lz4.c
+++ b/drivers/block/zram/backend_lz4.c
@@ -10,40 +10,44 @@ struct lz4_ctx {
s32 level;
};
-static void lz4_destroy(void *ctx)
+static void lz4_destroy(struct zcomp_ctx *ctx)
{
- struct lz4_ctx *zctx = ctx;
+ struct lz4_ctx *zctx = ctx->context;
+
+ if (!zctx)
+ return;
vfree(zctx->mem);
kfree(zctx);
}
-static void *lz4_create(struct zcomp_params *params)
+static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- struct lz4_ctx *ctx;
+ struct lz4_ctx *zctx;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return NULL;
+ zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
+ if (!zctx)
+ return -ENOMEM;
+ ctx->context = zctx;
if (params->level != ZCOMP_PARAM_NO_LEVEL)
- ctx->level = params->level;
+ zctx->level = params->level;
else
- ctx->level = LZ4_ACCELERATION_DEFAULT;
+ zctx->level = LZ4_ACCELERATION_DEFAULT;
- ctx->mem = vmalloc(LZ4_MEM_COMPRESS);
- if (!ctx->mem)
+ zctx->mem = vmalloc(LZ4_MEM_COMPRESS);
+ if (!zctx->mem)
goto error;
- return ctx;
+ return 0;
error:
lz4_destroy(ctx);
- return NULL;
+ return -EINVAL;
}
-static int lz4_compress(void *ctx, struct zcomp_req *req)
+static int lz4_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
- struct lz4_ctx *zctx = ctx;
+ struct lz4_ctx *zctx = ctx->context;
int ret;
ret = LZ4_compress_fast(req->src, req->dst, req->src_len,
@@ -54,7 +58,7 @@ static int lz4_compress(void *ctx, struct zcomp_req *req)
return 0;
}
-static int lz4_decompress(void *ctx, struct zcomp_req *req)
+static int lz4_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
int ret;
diff --git a/drivers/block/zram/backend_lz4hc.c b/drivers/block/zram/backend_lz4hc.c
index 610dadc09751..6da71ec5fc05 100644
--- a/drivers/block/zram/backend_lz4hc.c
+++ b/drivers/block/zram/backend_lz4hc.c
@@ -10,40 +10,44 @@ struct lz4hc_ctx {
s32 level;
};
-static void lz4hc_destroy(void *ctx)
+static void lz4hc_destroy(struct zcomp_ctx *ctx)
{
- struct lz4hc_ctx *zctx = ctx;
+ struct lz4hc_ctx *zctx = ctx->context;
+
+ if (!zctx)
+ return;
vfree(zctx->mem);
kfree(zctx);
}
-static void *lz4hc_create(struct zcomp_params *params)
+static int lz4hc_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- struct lz4hc_ctx *ctx;
+ struct lz4hc_ctx *zctx;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return NULL;
+ zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
+ if (!zctx)
+ return -ENOMEM;
+ ctx->context = zctx;
if (params->level != ZCOMP_PARAM_NO_LEVEL)
- ctx->level = params->level;
+ zctx->level = params->level;
else
- ctx->level = LZ4HC_DEFAULT_CLEVEL;
+ zctx->level = LZ4HC_DEFAULT_CLEVEL;
- ctx->mem = vmalloc(LZ4HC_MEM_COMPRESS);
- if (!ctx->mem)
+ zctx->mem = vmalloc(LZ4HC_MEM_COMPRESS);
+ if (!zctx->mem)
goto error;
- return ctx;
+ return 0;
error:
lz4hc_destroy(ctx);
- return NULL;
+ return -EINVAL;
}
-static int lz4hc_compress(void *ctx, struct zcomp_req *req)
+static int lz4hc_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
- struct lz4hc_ctx *zctx = ctx;
+ struct lz4hc_ctx *zctx = ctx->context;
int ret;
ret = LZ4_compress_HC(req->src, req->dst, req->src_len, req->dst_len,
@@ -54,7 +58,7 @@ static int lz4hc_compress(void *ctx, struct zcomp_req *req)
return 0;
}
-static int lz4hc_decompress(void *ctx, struct zcomp_req *req)
+static int lz4hc_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
int ret;
diff --git a/drivers/block/zram/backend_lzo.c b/drivers/block/zram/backend_lzo.c
index 88f1aa5683f3..81fbad286092 100644
--- a/drivers/block/zram/backend_lzo.c
+++ b/drivers/block/zram/backend_lzo.c
@@ -6,26 +6,29 @@
#include "backend_lzo.h"
-static void *lzo_create(struct zcomp_params *params)
+static int lzo_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+ ctx->context = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+ if (!ctx->context)
+ return -ENOMEM;
+ return 0;
}
-static void lzo_destroy(void *ctx)
+static void lzo_destroy(struct zcomp_ctx *ctx)
{
- kfree(ctx);
+ kfree(ctx->context);
}
-static int lzo_compress(void *ctx, struct zcomp_req *req)
+static int lzo_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
int ret;
ret = lzo1x_1_compress(req->src, req->src_len, req->dst,
- &req->dst_len, ctx);
+ &req->dst_len, ctx->context);
return ret == LZO_E_OK ? 0 : ret;
}
-static int lzo_decompress(void *ctx, struct zcomp_req *req)
+static int lzo_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
int ret;
diff --git a/drivers/block/zram/backend_lzorle.c b/drivers/block/zram/backend_lzorle.c
index f05820929a74..99c9da8f116e 100644
--- a/drivers/block/zram/backend_lzorle.c
+++ b/drivers/block/zram/backend_lzorle.c
@@ -6,26 +6,29 @@
#include "backend_lzorle.h"
-static void *lzorle_create(struct zcomp_params *params)
+static int lzorle_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+ ctx->context = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+ if (!ctx->context)
+ return -ENOMEM;
+ return 0;
}
-static void lzorle_destroy(void *ctx)
+static void lzorle_destroy(struct zcomp_ctx *ctx)
{
- kfree(ctx);
+ kfree(ctx->context);
}
-static int lzorle_compress(void *ctx, struct zcomp_req *req)
+static int lzorle_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
int ret;
ret = lzorle1x_1_compress(req->src, req->src_len, req->dst,
- &req->dst_len, ctx);
+ &req->dst_len, ctx->context);
return ret == LZO_E_OK ? 0 : ret;
}
-static int lzorle_decompress(void *ctx, struct zcomp_req *req)
+static int lzorle_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
int ret;
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index 19eba65f44c9..9f000dedf1ad 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -16,60 +16,64 @@ struct zstd_ctx {
s32 level;
};
-static void zstd_destroy(void *ctx)
+static void zstd_destroy(struct zcomp_ctx *ctx)
{
- struct zstd_ctx *zctx = ctx;
+ struct zstd_ctx *zctx = ctx->context;
+
+ if (!zctx)
+ return;
vfree(zctx->cctx_mem);
vfree(zctx->dctx_mem);
kfree(zctx);
}
-static void *zstd_create(struct zcomp_params *params)
+static int zstd_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
+ struct zstd_ctx *zctx;
zstd_parameters prm;
- struct zstd_ctx *ctx;
size_t sz;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return NULL;
+ zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
+ if (!zctx)
+ return -ENOMEM;
+ ctx->context = zctx;
if (params->level != ZCOMP_PARAM_NO_LEVEL)
- ctx->level = params->level;
+ zctx->level = params->level;
else
- ctx->level = zstd_default_clevel();
+ zctx->level = zstd_default_clevel();
- prm = zstd_get_params(ctx->level, PAGE_SIZE);
- ctx->cprm = zstd_get_params(ctx->level, PAGE_SIZE);
+ prm = zstd_get_params(zctx->level, PAGE_SIZE);
+ zctx->cprm = zstd_get_params(zctx->level, PAGE_SIZE);
sz = zstd_cctx_workspace_bound(&prm.cParams);
- ctx->cctx_mem = vzalloc(sz);
- if (!ctx->cctx_mem)
+ zctx->cctx_mem = vzalloc(sz);
+ if (!zctx->cctx_mem)
goto error;
- ctx->cctx = zstd_init_cctx(ctx->cctx_mem, sz);
- if (!ctx->cctx)
+ zctx->cctx = zstd_init_cctx(zctx->cctx_mem, sz);
+ if (!zctx->cctx)
goto error;
sz = zstd_dctx_workspace_bound();
- ctx->dctx_mem = vzalloc(sz);
- if (!ctx->dctx_mem)
+ zctx->dctx_mem = vzalloc(sz);
+ if (!zctx->dctx_mem)
goto error;
- ctx->dctx = zstd_init_dctx(ctx->dctx_mem, sz);
- if (!ctx->dctx)
+ zctx->dctx = zstd_init_dctx(zctx->dctx_mem, sz);
+ if (!zctx->dctx)
goto error;
- return ctx;
+ return 0;
error:
zstd_destroy(ctx);
- return NULL;
+ return -EINVAL;
}
-static int zstd_compress(void *ctx, struct zcomp_req *req)
+static int zstd_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
- struct zstd_ctx *zctx = ctx;
+ struct zstd_ctx *zctx = ctx->context;
size_t ret;
ret = zstd_compress_cctx(zctx->cctx, req->dst, req->dst_len,
@@ -80,9 +84,9 @@ static int zstd_compress(void *ctx, struct zcomp_req *req)
return 0;
}
-static int zstd_decompress(void *ctx, struct zcomp_req *req)
+static int zstd_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
{
- struct zstd_ctx *zctx = ctx;
+ struct zstd_ctx *zctx = ctx->context;
size_t ret;
ret = zstd_decompress_dctx(zctx->dctx, req->dst, req->dst_len,
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 20ad7b6fe62f..96f07287e571 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -45,23 +45,25 @@ static const struct zcomp_ops *backends[] = {
static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm)
{
- if (zstrm->ctx)
- comp->ops->destroy_ctx(zstrm->ctx);
+ comp->ops->destroy_ctx(&zstrm->ctx);
vfree(zstrm->buffer);
- zstrm->ctx = NULL;
zstrm->buffer = NULL;
}
static int zcomp_strm_init(struct zcomp *comp, struct zcomp_strm *zstrm)
{
- zstrm->ctx = comp->ops->create_ctx(comp->params);
+ int ret;
+
+ ret = comp->ops->create_ctx(comp->params, &zstrm->ctx);
+ if (ret)
+ return ret;
/*
* allocate 2 pages. 1 for compressed data, plus 1 extra for the
* case when compressed size is larger than the original one
*/
zstrm->buffer = vzalloc(2 * PAGE_SIZE);
- if (!zstrm->ctx || !zstrm->buffer) {
+ if (!zstrm->buffer) {
zcomp_strm_free(comp, zstrm);
return -ENOMEM;
}
@@ -127,7 +129,7 @@ int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm,
};
int ret;
- ret = comp->ops->compress(zstrm->ctx, &req);
+ ret = comp->ops->compress(&zstrm->ctx, &req);
if (!ret)
*dst_len = req.dst_len;
return ret;
@@ -143,7 +145,7 @@ int zcomp_decompress(struct zcomp *comp, struct zcomp_strm *zstrm,
.dst_len = PAGE_SIZE,
};
- return comp->ops->decompress(zstrm->ctx, &req);
+ return comp->ops->decompress(&zstrm->ctx, &req);
}
int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node)
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
index bbc48094f826..1d8920c2d449 100644
--- a/drivers/block/zram/zcomp.h
+++ b/drivers/block/zram/zcomp.h
@@ -13,12 +13,20 @@ struct zcomp_params {
s32 level;
};
+/*
+ * Run-time driver context - scratch buffers, etc. It is modified during
+ * request execution (compression/decompression), cannot be shared, so
+ * it's in per-CPU area.
+ */
+struct zcomp_ctx {
+ void *context;
+};
+
struct zcomp_strm {
- /* The members ->buffer and ->tfm are protected by ->lock. */
local_lock_t lock;
- /* compression/decompression buffer */
+ /* compression buffer */
void *buffer;
- void *ctx;
+ struct zcomp_ctx ctx;
};
struct zcomp_req {
@@ -30,11 +38,12 @@ struct zcomp_req {
};
struct zcomp_ops {
- int (*compress)(void *ctx, struct zcomp_req *req);
- int (*decompress)(void *ctx, struct zcomp_req *req);
+ int (*compress)(struct zcomp_ctx *ctx, struct zcomp_req *req);
+ int (*decompress)(struct zcomp_ctx *ctx, struct zcomp_req *req);
- void *(*create_ctx)(struct zcomp_params *params);
- void (*destroy_ctx)(void *ctx);
+ int (*create_ctx)(struct zcomp_params *params,
+ struct zcomp_ctx *ctx);
+ void (*destroy_ctx)(struct zcomp_ctx *ctx);
const char *name;
};
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 19/24] zram: move immutable comp params away from per-CPU context
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (17 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 18/24] zram: introduce zcomp_ctx structure Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 20/24] zram: add dictionary support to lz4 Sergey Senozhatsky
` (4 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Immutable params never change once comp has been allocated
and setup, so we don't need to store multiple copies of
them in each per-CPU backend context. Move those to
per-comp zcomp_params and pass it to backends callbacks
for requests execution. Basically, this means parameters
sharing between different contexts.
Also introduce two new backends callbacks: setup_params()
and release_params(). First, we need to validate params
in a driver-specific way; second, driver may want to
allocate its specific representation of the params which
is needed to execute requests.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/backend_842.c | 17 ++++++++--
drivers/block/zram/backend_deflate.c | 29 +++++++++++-----
drivers/block/zram/backend_lz4.c | 51 +++++++++++-----------------
drivers/block/zram/backend_lz4hc.c | 51 +++++++++++-----------------
drivers/block/zram/backend_lzo.c | 17 ++++++++--
drivers/block/zram/backend_lzorle.c | 17 ++++++++--
drivers/block/zram/backend_zstd.c | 47 ++++++++++++++++++-------
drivers/block/zram/zcomp.c | 17 +++++++---
drivers/block/zram/zcomp.h | 20 ++++++++---
9 files changed, 168 insertions(+), 98 deletions(-)
diff --git a/drivers/block/zram/backend_842.c b/drivers/block/zram/backend_842.c
index 2f1202322264..10d9d5c60f53 100644
--- a/drivers/block/zram/backend_842.c
+++ b/drivers/block/zram/backend_842.c
@@ -7,6 +7,15 @@
#include "backend_842.h"
+static void release_params_842(struct zcomp_params *params)
+{
+}
+
+static int setup_params_842(struct zcomp_params *params)
+{
+ return 0;
+}
+
static void destroy_842(struct zcomp_ctx *ctx)
{
kfree(ctx->context);
@@ -20,7 +29,8 @@ static int create_842(struct zcomp_params *params, struct zcomp_ctx *ctx)
return 0;
}
-static int compress_842(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int compress_842(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
unsigned int dlen = req->dst_len;
int ret;
@@ -32,7 +42,8 @@ static int compress_842(struct zcomp_ctx *ctx, struct zcomp_req *req)
return ret;
}
-static int decompress_842(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int decompress_842(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
unsigned int dlen = req->dst_len;
@@ -44,5 +55,7 @@ const struct zcomp_ops backend_842 = {
.decompress = decompress_842,
.create_ctx = create_842,
.destroy_ctx = destroy_842,
+ .setup_params = setup_params_842,
+ .release_params = release_params_842,
.name = "842",
};
diff --git a/drivers/block/zram/backend_deflate.c b/drivers/block/zram/backend_deflate.c
index eae4ee35c1df..0f7f252c12f4 100644
--- a/drivers/block/zram/backend_deflate.c
+++ b/drivers/block/zram/backend_deflate.c
@@ -14,9 +14,20 @@
struct deflate_ctx {
struct z_stream_s cctx;
struct z_stream_s dctx;
- s32 level;
};
+static void deflate_release_params(struct zcomp_params *params)
+{
+}
+
+static int deflate_setup_params(struct zcomp_params *params)
+{
+ if (params->level == ZCOMP_PARAM_NO_LEVEL)
+ params->level = Z_DEFAULT_COMPRESSION;
+
+ return 0;
+}
+
static void deflate_destroy(struct zcomp_ctx *ctx)
{
struct deflate_ctx *zctx = ctx->context;
@@ -46,17 +57,12 @@ static int deflate_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
return -ENOMEM;
ctx->context = zctx;
- if (params->level != ZCOMP_PARAM_NO_LEVEL)
- zctx->level = params->level;
- else
- zctx->level = Z_DEFAULT_COMPRESSION;
-
sz = zlib_deflate_workspacesize(-DEFLATE_DEF_WINBITS, MAX_MEM_LEVEL);
zctx->cctx.workspace = vzalloc(sz);
if (!zctx->cctx.workspace)
goto error;
- ret = zlib_deflateInit2(&zctx->cctx, zctx->level, Z_DEFLATED,
+ ret = zlib_deflateInit2(&zctx->cctx, params->level, Z_DEFLATED,
-DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
Z_DEFAULT_STRATEGY);
if (ret != Z_OK)
@@ -78,7 +84,8 @@ static int deflate_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
return -EINVAL;
}
-static int deflate_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int deflate_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
struct deflate_ctx *zctx = ctx->context;
struct z_stream_s *deflate;
@@ -102,7 +109,9 @@ static int deflate_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
return 0;
}
-static int deflate_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int deflate_decompress(struct zcomp_params *params,
+ struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
struct deflate_ctx *zctx = ctx->context;
struct z_stream_s *inflate;
@@ -131,5 +140,7 @@ const struct zcomp_ops backend_deflate = {
.decompress = deflate_decompress,
.create_ctx = deflate_create,
.destroy_ctx = deflate_destroy,
+ .setup_params = deflate_setup_params,
+ .release_params = deflate_release_params,
.name = "deflate",
};
diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c
index e2d951e62746..cf3c029bd5ad 100644
--- a/drivers/block/zram/backend_lz4.c
+++ b/drivers/block/zram/backend_lz4.c
@@ -5,60 +5,47 @@
#include "backend_lz4.h"
-struct lz4_ctx {
- void *mem;
- s32 level;
-};
+static void lz4_release_params(struct zcomp_params *params)
+{
+}
-static void lz4_destroy(struct zcomp_ctx *ctx)
+static int lz4_setup_params(struct zcomp_params *params)
{
- struct lz4_ctx *zctx = ctx->context;
+ if (params->level == ZCOMP_PARAM_NO_LEVEL)
+ params->level = LZ4_ACCELERATION_DEFAULT;
- if (!zctx)
- return;
+ return 0;
+}
- vfree(zctx->mem);
- kfree(zctx);
+static void lz4_destroy(struct zcomp_ctx *ctx)
+{
+ vfree(ctx->context);
}
static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- struct lz4_ctx *zctx;
-
- zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
- if (!zctx)
+ ctx->context = vmalloc(LZ4_MEM_COMPRESS);
+ if (!ctx->context)
return -ENOMEM;
- ctx->context = zctx;
- if (params->level != ZCOMP_PARAM_NO_LEVEL)
- zctx->level = params->level;
- else
- zctx->level = LZ4_ACCELERATION_DEFAULT;
-
- zctx->mem = vmalloc(LZ4_MEM_COMPRESS);
- if (!zctx->mem)
- goto error;
-
return 0;
-error:
- lz4_destroy(ctx);
- return -EINVAL;
}
-static int lz4_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int lz4_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
- struct lz4_ctx *zctx = ctx->context;
int ret;
ret = LZ4_compress_fast(req->src, req->dst, req->src_len,
- req->dst_len, zctx->level, zctx->mem);
+ req->dst_len, params->level, ctx->context);
if (!ret)
return -EINVAL;
req->dst_len = ret;
return 0;
}
-static int lz4_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int lz4_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
int ret;
@@ -74,5 +61,7 @@ const struct zcomp_ops backend_lz4 = {
.decompress = lz4_decompress,
.create_ctx = lz4_create,
.destroy_ctx = lz4_destroy,
+ .setup_params = lz4_setup_params,
+ .release_params = lz4_release_params,
.name = "lz4",
};
diff --git a/drivers/block/zram/backend_lz4hc.c b/drivers/block/zram/backend_lz4hc.c
index 6da71ec5fc05..928a6ea78668 100644
--- a/drivers/block/zram/backend_lz4hc.c
+++ b/drivers/block/zram/backend_lz4hc.c
@@ -5,60 +5,47 @@
#include "backend_lz4hc.h"
-struct lz4hc_ctx {
- void *mem;
- s32 level;
-};
+static void lz4hc_release_params(struct zcomp_params *params)
+{
+}
-static void lz4hc_destroy(struct zcomp_ctx *ctx)
+static int lz4hc_setup_params(struct zcomp_params *params)
{
- struct lz4hc_ctx *zctx = ctx->context;
+ if (params->level == ZCOMP_PARAM_NO_LEVEL)
+ params->level = LZ4HC_DEFAULT_CLEVEL;
- if (!zctx)
- return;
+ return 0;
+}
- vfree(zctx->mem);
- kfree(zctx);
+static void lz4hc_destroy(struct zcomp_ctx *ctx)
+{
+ vfree(ctx->context);
}
static int lz4hc_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- struct lz4hc_ctx *zctx;
-
- zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
- if (!zctx)
+ ctx->context = vmalloc(LZ4HC_MEM_COMPRESS);
+ if (!ctx->context)
return -ENOMEM;
- ctx->context = zctx;
- if (params->level != ZCOMP_PARAM_NO_LEVEL)
- zctx->level = params->level;
- else
- zctx->level = LZ4HC_DEFAULT_CLEVEL;
-
- zctx->mem = vmalloc(LZ4HC_MEM_COMPRESS);
- if (!zctx->mem)
- goto error;
-
return 0;
-error:
- lz4hc_destroy(ctx);
- return -EINVAL;
}
-static int lz4hc_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int lz4hc_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
- struct lz4hc_ctx *zctx = ctx->context;
int ret;
ret = LZ4_compress_HC(req->src, req->dst, req->src_len, req->dst_len,
- zctx->level, zctx->mem);
+ params->level, ctx->context);
if (!ret)
return -EINVAL;
req->dst_len = ret;
return 0;
}
-static int lz4hc_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int lz4hc_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
int ret;
@@ -74,5 +61,7 @@ const struct zcomp_ops backend_lz4hc = {
.decompress = lz4hc_decompress,
.create_ctx = lz4hc_create,
.destroy_ctx = lz4hc_destroy,
+ .setup_params = lz4hc_setup_params,
+ .release_params = lz4hc_release_params,
.name = "lz4hc",
};
diff --git a/drivers/block/zram/backend_lzo.c b/drivers/block/zram/backend_lzo.c
index 81fbad286092..4c906beaae6b 100644
--- a/drivers/block/zram/backend_lzo.c
+++ b/drivers/block/zram/backend_lzo.c
@@ -6,6 +6,15 @@
#include "backend_lzo.h"
+static void lzo_release_params(struct zcomp_params *params)
+{
+}
+
+static int lzo_setup_params(struct zcomp_params *params)
+{
+ return 0;
+}
+
static int lzo_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
ctx->context = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
@@ -19,7 +28,8 @@ static void lzo_destroy(struct zcomp_ctx *ctx)
kfree(ctx->context);
}
-static int lzo_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int lzo_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
int ret;
@@ -28,7 +38,8 @@ static int lzo_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
return ret == LZO_E_OK ? 0 : ret;
}
-static int lzo_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int lzo_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
int ret;
@@ -42,5 +53,7 @@ const struct zcomp_ops backend_lzo = {
.decompress = lzo_decompress,
.create_ctx = lzo_create,
.destroy_ctx = lzo_destroy,
+ .setup_params = lzo_setup_params,
+ .release_params = lzo_release_params,
.name = "lzo",
};
diff --git a/drivers/block/zram/backend_lzorle.c b/drivers/block/zram/backend_lzorle.c
index 99c9da8f116e..10640c96cbfc 100644
--- a/drivers/block/zram/backend_lzorle.c
+++ b/drivers/block/zram/backend_lzorle.c
@@ -6,6 +6,15 @@
#include "backend_lzorle.h"
+static void lzorle_release_params(struct zcomp_params *params)
+{
+}
+
+static int lzorle_setup_params(struct zcomp_params *params)
+{
+ return 0;
+}
+
static int lzorle_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
ctx->context = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
@@ -19,7 +28,8 @@ static void lzorle_destroy(struct zcomp_ctx *ctx)
kfree(ctx->context);
}
-static int lzorle_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int lzorle_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
int ret;
@@ -28,7 +38,8 @@ static int lzorle_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
return ret == LZO_E_OK ? 0 : ret;
}
-static int lzorle_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int lzorle_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
int ret;
@@ -42,5 +53,7 @@ const struct zcomp_ops backend_lzorle = {
.decompress = lzorle_decompress,
.create_ctx = lzorle_create,
.destroy_ctx = lzorle_destroy,
+ .setup_params = lzorle_setup_params,
+ .release_params = lzorle_release_params,
.name = "lzo-rle",
};
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index 9f000dedf1ad..5b33daf4f645 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -10,12 +10,36 @@
struct zstd_ctx {
zstd_cctx *cctx;
zstd_dctx *dctx;
- zstd_parameters cprm;
void *cctx_mem;
void *dctx_mem;
- s32 level;
};
+struct zstd_params {
+ zstd_parameters cprm;
+};
+
+static void zstd_release_params(struct zcomp_params *params)
+{
+ kfree(params->drv_data);
+}
+
+static int zstd_setup_params(struct zcomp_params *params)
+{
+ struct zstd_params *zp;
+
+ zp = kzalloc(sizeof(*zp), GFP_KERNEL);
+ if (!zp)
+ return -ENOMEM;
+
+ if (params->level == ZCOMP_PARAM_NO_LEVEL)
+ params->level = zstd_default_clevel();
+
+ zp->cprm = zstd_get_params(params->level, PAGE_SIZE);
+ params->drv_data = zp;
+
+ return 0;
+}
+
static void zstd_destroy(struct zcomp_ctx *ctx)
{
struct zstd_ctx *zctx = ctx->context;
@@ -39,13 +63,7 @@ static int zstd_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
return -ENOMEM;
ctx->context = zctx;
- if (params->level != ZCOMP_PARAM_NO_LEVEL)
- zctx->level = params->level;
- else
- zctx->level = zstd_default_clevel();
-
- prm = zstd_get_params(zctx->level, PAGE_SIZE);
- zctx->cprm = zstd_get_params(zctx->level, PAGE_SIZE);
+ prm = zstd_get_params(params->level, PAGE_SIZE);
sz = zstd_cctx_workspace_bound(&prm.cParams);
zctx->cctx_mem = vzalloc(sz);
if (!zctx->cctx_mem)
@@ -71,20 +89,23 @@ static int zstd_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
return -EINVAL;
}
-static int zstd_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int zstd_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
+ struct zstd_params *zp = params->drv_data;
struct zstd_ctx *zctx = ctx->context;
size_t ret;
ret = zstd_compress_cctx(zctx->cctx, req->dst, req->dst_len,
- req->src, req->src_len, &zctx->cprm);
+ req->src, req->src_len, &zp->cprm);
if (zstd_is_error(ret))
return -EINVAL;
req->dst_len = ret;
return 0;
}
-static int zstd_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
+static int zstd_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req)
{
struct zstd_ctx *zctx = ctx->context;
size_t ret;
@@ -101,5 +122,7 @@ const struct zcomp_ops backend_zstd = {
.decompress = zstd_decompress,
.create_ctx = zstd_create,
.destroy_ctx = zstd_destroy,
+ .setup_params = zstd_setup_params,
+ .release_params = zstd_release_params,
.name = "zstd",
};
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 96f07287e571..bb514403e305 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -129,7 +129,7 @@ int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm,
};
int ret;
- ret = comp->ops->compress(&zstrm->ctx, &req);
+ ret = comp->ops->compress(comp->params, &zstrm->ctx, &req);
if (!ret)
*dst_len = req.dst_len;
return ret;
@@ -145,7 +145,7 @@ int zcomp_decompress(struct zcomp *comp, struct zcomp_strm *zstrm,
.dst_len = PAGE_SIZE,
};
- return comp->ops->decompress(&zstrm->ctx, &req);
+ return comp->ops->decompress(comp->params, &zstrm->ctx, &req);
}
int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node)
@@ -173,7 +173,7 @@ int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node)
return 0;
}
-static int zcomp_init(struct zcomp *comp)
+static int zcomp_init(struct zcomp *comp, struct zcomp_params *params)
{
int ret;
@@ -181,12 +181,19 @@ static int zcomp_init(struct zcomp *comp)
if (!comp->stream)
return -ENOMEM;
+ comp->params = params;
+ ret = comp->ops->setup_params(comp->params);
+ if (ret)
+ goto cleanup;
+
ret = cpuhp_state_add_instance(CPUHP_ZCOMP_PREPARE, &comp->node);
if (ret < 0)
goto cleanup;
+
return 0;
cleanup:
+ comp->ops->release_params(comp->params);
free_percpu(comp->stream);
return ret;
}
@@ -194,6 +201,7 @@ static int zcomp_init(struct zcomp *comp)
void zcomp_destroy(struct zcomp *comp)
{
cpuhp_state_remove_instance(CPUHP_ZCOMP_PREPARE, &comp->node);
+ comp->ops->release_params(comp->params);
free_percpu(comp->stream);
kfree(comp);
}
@@ -215,14 +223,13 @@ struct zcomp *zcomp_create(const char *alg, struct zcomp_params *params)
if (!comp)
return ERR_PTR(-ENOMEM);
- comp->params = params;
comp->ops = lookup_backend_ops(alg);
if (!comp->ops) {
kfree(comp);
return ERR_PTR(-EINVAL);
}
- error = zcomp_init(comp);
+ error = zcomp_init(comp, params);
if (error) {
kfree(comp);
return ERR_PTR(error);
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
index 1d8920c2d449..ad5762813842 100644
--- a/drivers/block/zram/zcomp.h
+++ b/drivers/block/zram/zcomp.h
@@ -7,10 +7,18 @@
#define ZCOMP_PARAM_NO_LEVEL INT_MIN
+/*
+ * Immutable driver (backend) parameters. The driver may attach private
+ * data to it (e.g. driver representation of the dictionary, etc.).
+ *
+ * This data is kept per-comp and is shared among execution contexts.
+ */
struct zcomp_params {
void *dict;
size_t dict_sz;
s32 level;
+
+ void *drv_data;
};
/*
@@ -38,13 +46,17 @@ struct zcomp_req {
};
struct zcomp_ops {
- int (*compress)(struct zcomp_ctx *ctx, struct zcomp_req *req);
- int (*decompress)(struct zcomp_ctx *ctx, struct zcomp_req *req);
+ int (*compress)(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req);
+ int (*decompress)(struct zcomp_params *params, struct zcomp_ctx *ctx,
+ struct zcomp_req *req);
- int (*create_ctx)(struct zcomp_params *params,
- struct zcomp_ctx *ctx);
+ int (*create_ctx)(struct zcomp_params *params, struct zcomp_ctx *ctx);
void (*destroy_ctx)(struct zcomp_ctx *ctx);
+ int (*setup_params)(struct zcomp_params *params);
+ void (*release_params)(struct zcomp_params *params);
+
const char *name;
};
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 20/24] zram: add dictionary support to lz4
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (18 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 19/24] zram: move immutable comp params away from per-CPU context Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 21/24] zram: add dictionary support to lz4hc Sergey Senozhatsky
` (3 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Support pre-trained dictionary param. lz4 doesn't
mandate specific format of the dictionary and even
zstd --train can be used to train a dictionary for
lz4, according to [1].
TEST
====
*** lz4
/sys/block/zram0/mm_stat
1750654976 664188565 676864000 0 676864000 1 0 34288 34288
*** lz4 dict=/etc/lz4-dict-amd64
/sys/block/zram0/mm_stat
1750638592 619891141 632053760 0 632053760 1 0 34278 34278
*** lz4 level=5 dict=/etc/lz4-dict-amd64
/sys/block/zram0/mm_stat
1750638592 727174243 740810752 0 740810752 1 0 34437 34437
[1] https://github.com/lz4/lz4/issues/557
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/backend_lz4.c | 74 +++++++++++++++++++++++++++++---
1 file changed, 67 insertions(+), 7 deletions(-)
diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c
index cf3c029bd5ad..847f3334eb38 100644
--- a/drivers/block/zram/backend_lz4.c
+++ b/drivers/block/zram/backend_lz4.c
@@ -5,6 +5,13 @@
#include "backend_lz4.h"
+struct lz4_ctx {
+ void *mem;
+
+ LZ4_streamDecode_t *dstrm;
+ LZ4_stream_t *cstrm;
+};
+
static void lz4_release_params(struct zcomp_params *params)
{
}
@@ -19,25 +26,66 @@ static int lz4_setup_params(struct zcomp_params *params)
static void lz4_destroy(struct zcomp_ctx *ctx)
{
- vfree(ctx->context);
+ struct lz4_ctx *zctx = ctx->context;
+
+ if (!zctx)
+ return;
+
+ vfree(zctx->mem);
+ kfree(zctx->dstrm);
+ kfree(zctx->cstrm);
+ kfree(zctx);
}
static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- ctx->context = vmalloc(LZ4_MEM_COMPRESS);
- if (!ctx->context)
+ struct lz4_ctx *zctx;
+
+ zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
+ if (!zctx)
return -ENOMEM;
+ ctx->context = zctx;
+ if (params->dict_sz == 0) {
+ zctx->mem = vmalloc(LZ4_MEM_COMPRESS);
+ if (!zctx->mem)
+ goto error;
+ } else {
+ zctx->dstrm = kzalloc(sizeof(*zctx->dstrm), GFP_KERNEL);
+ if (!zctx->dstrm)
+ goto error;
+
+ zctx->cstrm = kzalloc(sizeof(*zctx->cstrm), GFP_KERNEL);
+ if (!zctx->cstrm)
+ goto error;
+ }
+
return 0;
+
+error:
+ lz4_destroy(ctx);
+ return -ENOMEM;
}
static int lz4_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
struct zcomp_req *req)
{
+ struct lz4_ctx *zctx = ctx->context;
int ret;
- ret = LZ4_compress_fast(req->src, req->dst, req->src_len,
- req->dst_len, params->level, ctx->context);
+ if (!zctx->cstrm) {
+ ret = LZ4_compress_fast(req->src, req->dst, req->src_len,
+ req->dst_len, params->level,
+ 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;
+ ret = LZ4_compress_fast_continue(zctx->cstrm, req->src,
+ req->dst, req->src_len,
+ req->dst_len, params->level);
+ }
if (!ret)
return -EINVAL;
req->dst_len = ret;
@@ -47,10 +95,22 @@ static int lz4_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
static int lz4_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
struct zcomp_req *req)
{
+ struct lz4_ctx *zctx = ctx->context;
int ret;
- ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
- req->dst_len);
+ if (!zctx->dstrm) {
+ ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
+ req->dst_len);
+ } else {
+ /* Dstrm needs to be reset */
+ ret = LZ4_setStreamDecode(zctx->dstrm, params->dict,
+ params->dict_sz);
+ if (!ret)
+ return -EINVAL;
+ ret = LZ4_decompress_safe_continue(zctx->dstrm, req->src,
+ req->dst, req->src_len,
+ req->dst_len);
+ }
if (ret < 0)
return -EINVAL;
return 0;
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 21/24] zram: add dictionary support to lz4hc
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (19 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 20/24] zram: add dictionary support to lz4 Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 22/24] zram: add dictionary support to zstd backend Sergey Senozhatsky
` (2 subsequent siblings)
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Support pre-trained dictionary param. Just like lz4,
lz4hc doesn't mandate specific format of the dictionary
and zstd --train can be used to train a dictionary for
lz4, according to [1].
TEST
====
*** lz4hc
/sys/block/zram0/mm_stat
1750638592 608954620 621031424 0 621031424 1 0 34288 34288
*** lz4hc dict=/etc/lz4-dict-amd64
/sys/block/zram0/mm_stat
1750671360 505068582 514994176 0 514994176 1 0 34278 34278
[1] https://github.com/lz4/lz4/issues/557
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/backend_lz4hc.c | 75 +++++++++++++++++++++++++++---
1 file changed, 68 insertions(+), 7 deletions(-)
diff --git a/drivers/block/zram/backend_lz4hc.c b/drivers/block/zram/backend_lz4hc.c
index 928a6ea78668..5f37d5abcaeb 100644
--- a/drivers/block/zram/backend_lz4hc.c
+++ b/drivers/block/zram/backend_lz4hc.c
@@ -5,6 +5,13 @@
#include "backend_lz4hc.h"
+struct lz4hc_ctx {
+ void *mem;
+
+ LZ4_streamDecode_t *dstrm;
+ LZ4_streamHC_t *cstrm;
+};
+
static void lz4hc_release_params(struct zcomp_params *params)
{
}
@@ -19,25 +26,67 @@ static int lz4hc_setup_params(struct zcomp_params *params)
static void lz4hc_destroy(struct zcomp_ctx *ctx)
{
- vfree(ctx->context);
+ struct lz4hc_ctx *zctx = ctx->context;
+
+ if (!zctx)
+ return;
+
+ kfree(zctx->dstrm);
+ kfree(zctx->cstrm);
+ vfree(zctx->mem);
+ kfree(zctx);
}
static int lz4hc_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
{
- ctx->context = vmalloc(LZ4HC_MEM_COMPRESS);
- if (!ctx->context)
+ struct lz4hc_ctx *zctx;
+
+ zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
+ if (!zctx)
return -ENOMEM;
+ ctx->context = zctx;
+ if (params->dict_sz == 0) {
+ zctx->mem = vmalloc(LZ4HC_MEM_COMPRESS);
+ if (!zctx->mem)
+ goto error;
+ } else {
+ zctx->dstrm = kzalloc(sizeof(*zctx->dstrm), GFP_KERNEL);
+ if (!zctx->dstrm)
+ goto error;
+
+ zctx->cstrm = kzalloc(sizeof(*zctx->cstrm), GFP_KERNEL);
+ if (!zctx->cstrm)
+ goto error;
+ }
+
return 0;
+
+error:
+ lz4hc_destroy(ctx);
+ return -EINVAL;
}
static int lz4hc_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
struct zcomp_req *req)
{
+ struct lz4hc_ctx *zctx = ctx->context;
int ret;
- ret = LZ4_compress_HC(req->src, req->dst, req->src_len, req->dst_len,
- params->level, ctx->context);
+ if (!zctx->cstrm) {
+ ret = LZ4_compress_HC(req->src, req->dst, req->src_len,
+ req->dst_len, params->level,
+ zctx->mem);
+ } else {
+ /* Cstrm needs to be reset */
+ LZ4_resetStreamHC(zctx->cstrm, params->level);
+ ret = LZ4_loadDictHC(zctx->cstrm, params->dict,
+ params->dict_sz);
+ if (ret != params->dict_sz)
+ return -EINVAL;
+ ret = LZ4_compress_HC_continue(zctx->cstrm, req->src, req->dst,
+ req->src_len, req->dst_len);
+ }
if (!ret)
return -EINVAL;
req->dst_len = ret;
@@ -47,10 +96,22 @@ static int lz4hc_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
static int lz4hc_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
struct zcomp_req *req)
{
+ struct lz4hc_ctx *zctx = ctx->context;
int ret;
- ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
- req->dst_len);
+ if (!zctx->dstrm) {
+ ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
+ req->dst_len);
+ } else {
+ /* Dstrm needs to be reset */
+ ret = LZ4_setStreamDecode(zctx->dstrm, params->dict,
+ params->dict_sz);
+ if (!ret)
+ return -EINVAL;
+ ret = LZ4_decompress_safe_continue(zctx->dstrm, req->src,
+ req->dst, req->src_len,
+ req->dst_len);
+ }
if (ret < 0)
return -EINVAL;
return 0;
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 22/24] zram: add dictionary support to zstd backend
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (20 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 21/24] zram: add dictionary support to lz4hc Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 23/24] Documentation/zram: add documentation for algorithm parameters Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 24/24] zram: support priority parameter in recompression Sergey Senozhatsky
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
This adds support for pre-trained zstd dictionaries [1]
Dictionary is setup in params once (per-comp) and loaded
to Cctx and Dctx by reference, so we don't allocate extra
memory.
TEST
====
*** zstd
/sys/block/zram0/mm_stat
1750654976 504565092 514203648 0 514203648 1 0 34204 34204
*** zstd dict=/etc/zstd-dict-amd64
/sys/block/zram0/mm_stat
1750638592 465851259 475373568 0 475373568 1 0 34185 34185
*** zstd level=8 dict=/etc/zstd-dict-amd64
/sys/block/zram0/mm_stat
1750642688 430765171 439955456 0 439955456 1 0 34185 34185
[1] https://github.com/facebook/zstd/blob/dev/programs/zstd.1.md#dictionary-builder
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/block/zram/backend_zstd.c | 150 ++++++++++++++++++++++++------
1 file changed, 124 insertions(+), 26 deletions(-)
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index 5b33daf4f645..1184c0036f44 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -15,29 +15,87 @@ struct zstd_ctx {
};
struct zstd_params {
+ zstd_custom_mem custom_mem;
+ zstd_cdict *cdict;
+ zstd_ddict *ddict;
zstd_parameters cprm;
};
+/*
+ * For C/D dictionaries we need to provide zstd with zstd_custom_mem,
+ * which zstd uses internally to allocate/free memory when needed.
+ *
+ * This means that allocator.customAlloc() can be called from zcomp_compress()
+ * under local-lock (per-CPU compression stream), in which case we must use
+ * GFP_ATOMIC.
+ *
+ * Another complication here is that we can be configured as a swap device.
+ */
+static void *zstd_custom_alloc(void *opaque, size_t size)
+{
+ if (!preemptible())
+ return kvzalloc(size, GFP_ATOMIC);
+
+ return kvzalloc(size, __GFP_KSWAPD_RECLAIM | __GFP_NOWARN);
+}
+
+static void zstd_custom_free(void *opaque, void *address)
+{
+ kvfree(address);
+}
+
static void zstd_release_params(struct zcomp_params *params)
{
- kfree(params->drv_data);
+ struct zstd_params *zp = params->drv_data;
+
+ params->drv_data = NULL;
+ if (!zp)
+ return;
+
+ zstd_free_cdict(zp->cdict);
+ zstd_free_ddict(zp->ddict);
+ kfree(zp);
}
static int zstd_setup_params(struct zcomp_params *params)
{
+ zstd_compression_parameters prm;
struct zstd_params *zp;
zp = kzalloc(sizeof(*zp), GFP_KERNEL);
if (!zp)
return -ENOMEM;
+ params->drv_data = zp;
if (params->level == ZCOMP_PARAM_NO_LEVEL)
params->level = zstd_default_clevel();
zp->cprm = zstd_get_params(params->level, PAGE_SIZE);
- params->drv_data = zp;
+
+ zp->custom_mem.customAlloc = zstd_custom_alloc;
+ zp->custom_mem.customFree = zstd_custom_free;
+
+ prm = zstd_get_cparams(params->level, PAGE_SIZE,
+ params->dict_sz);
+
+ zp->cdict = zstd_create_cdict_byreference(params->dict,
+ params->dict_sz,
+ prm,
+ zp->custom_mem);
+ if (!zp->cdict)
+ goto error;
+
+ zp->ddict = zstd_create_ddict_byreference(params->dict,
+ params->dict_sz,
+ zp->custom_mem);
+ if (!zp->ddict)
+ goto error;
return 0;
+
+error:
+ zstd_release_params(params);
+ return -EINVAL;
}
static void zstd_destroy(struct zcomp_ctx *ctx)
@@ -47,8 +105,23 @@ static void zstd_destroy(struct zcomp_ctx *ctx)
if (!zctx)
return;
- vfree(zctx->cctx_mem);
- vfree(zctx->dctx_mem);
+ /*
+ * If ->cctx_mem and ->dctx_mem were allocated then we didn't use
+ * C/D dictionary and ->cctx / ->dctx were "embedded" into these
+ * buffers.
+ *
+ * If otherwise then we need to explicitly release ->cctx / ->dctx.
+ */
+ if (zctx->cctx_mem)
+ vfree(zctx->cctx_mem);
+ else
+ zstd_free_cctx(zctx->cctx);
+
+ if (zctx->dctx_mem)
+ vfree(zctx->dctx_mem);
+ else
+ zstd_free_dctx(zctx->dctx);
+
kfree(zctx);
}
@@ -63,28 +136,41 @@ static int zstd_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
return -ENOMEM;
ctx->context = zctx;
- prm = zstd_get_params(params->level, PAGE_SIZE);
- sz = zstd_cctx_workspace_bound(&prm.cParams);
- zctx->cctx_mem = vzalloc(sz);
- if (!zctx->cctx_mem)
- goto error;
-
- zctx->cctx = zstd_init_cctx(zctx->cctx_mem, sz);
- if (!zctx->cctx)
- goto error;
-
- sz = zstd_dctx_workspace_bound();
- zctx->dctx_mem = vzalloc(sz);
- if (!zctx->dctx_mem)
- goto error;
-
- zctx->dctx = zstd_init_dctx(zctx->dctx_mem, sz);
- if (!zctx->dctx)
- goto error;
+ if (params->dict_sz == 0) {
+ prm = zstd_get_params(params->level, PAGE_SIZE);
+ sz = zstd_cctx_workspace_bound(&prm.cParams);
+ zctx->cctx_mem = vzalloc(sz);
+ if (!zctx->cctx_mem)
+ goto error;
+
+ zctx->cctx = zstd_init_cctx(zctx->cctx_mem, sz);
+ if (!zctx->cctx)
+ goto error;
+
+ sz = zstd_dctx_workspace_bound();
+ zctx->dctx_mem = vzalloc(sz);
+ if (!zctx->dctx_mem)
+ goto error;
+
+ zctx->dctx = zstd_init_dctx(zctx->dctx_mem, sz);
+ if (!zctx->dctx)
+ goto error;
+ } else {
+ struct zstd_params *zp = params->drv_data;
+
+ zctx->cctx = zstd_create_cctx_advanced(zp->custom_mem);
+ if (!zctx->cctx)
+ goto error;
+
+ zctx->dctx = zstd_create_dctx_advanced(zp->custom_mem);
+ if (!zctx->dctx)
+ goto error;
+ }
return 0;
error:
+ zstd_release_params(params);
zstd_destroy(ctx);
return -EINVAL;
}
@@ -96,8 +182,14 @@ static int zstd_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
struct zstd_ctx *zctx = ctx->context;
size_t ret;
- ret = zstd_compress_cctx(zctx->cctx, req->dst, req->dst_len,
- req->src, req->src_len, &zp->cprm);
+ if (params->dict_sz == 0)
+ ret = zstd_compress_cctx(zctx->cctx, req->dst, req->dst_len,
+ req->src, req->src_len, &zp->cprm);
+ else
+ ret = zstd_compress_using_cdict(zctx->cctx, req->dst,
+ req->dst_len, req->src,
+ req->src_len,
+ zp->cdict);
if (zstd_is_error(ret))
return -EINVAL;
req->dst_len = ret;
@@ -107,11 +199,17 @@ static int zstd_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
static int zstd_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
struct zcomp_req *req)
{
+ struct zstd_params *zp = params->drv_data;
struct zstd_ctx *zctx = ctx->context;
size_t ret;
- ret = zstd_decompress_dctx(zctx->dctx, req->dst, req->dst_len,
- req->src, req->src_len);
+ if (params->dict_sz == 0)
+ ret = zstd_decompress_dctx(zctx->dctx, req->dst, req->dst_len,
+ req->src, req->src_len);
+ else
+ ret = zstd_decompress_using_ddict(zctx->dctx, req->dst,
+ req->dst_len, req->src,
+ req->src_len, zp->ddict);
if (zstd_is_error(ret))
return -EINVAL;
return 0;
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 23/24] Documentation/zram: add documentation for algorithm parameters
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (21 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 22/24] zram: add dictionary support to zstd backend Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
2024-09-03 6:37 ` [PATCH] Documentation/zram: trivial fixup Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 24/24] zram: support priority parameter in recompression Sergey Senozhatsky
23 siblings, 1 reply; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
Document brief description of compression algorithms' parameters:
compression level and pre-trained dictionary.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
Documentation/admin-guide/blockdev/zram.rst | 45 +++++++++++++++++----
1 file changed, 38 insertions(+), 7 deletions(-)
diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst
index 96d81dc12528..bb52d2fc0587 100644
--- a/Documentation/admin-guide/blockdev/zram.rst
+++ b/Documentation/admin-guide/blockdev/zram.rst
@@ -105,7 +105,38 @@ Examples::
For the time being, the `comp_algorithm` content shows only compression
algorithms that are supported by zram.
-4) Set Disksize
+4) Set compression algorithm parameters: Optional
+=================================================
+
+Compression algorithms may support specific parameters which can be
+tweaked for particular dataset. ZRAM has an `algorithm_params` device
+attribute which provides a per-algorithm params configuration.
+
+For example, several compression algorithms support `level` parameter.
+In addition, certain compression algorithms support pre-trained dictionaries,
+which significantly change algorithms' characteristics. In order to configure
+compression algorithm to use external pre-trained dictionary, pass full
+path to the `dict` along with other parameters::
+
+ #pass path to pre-trained zstd dictionary
+ echo "algo=zstd dict=/etc/dictioary" > /sys/block/zram0/algorithm_params
+
+ #same, but using algorithm priority
+ echo "priority=1 dict=/etc/dictioary" > \
+ /sys/block/zram0/algorithm_params
+
+ #pass path to pre-trained zstd dictionary and compression level
+ echo "algo=zstd level=8 dict=/etc/dictioary" > \
+ /sys/block/zram0/algorithm_params
+
+Parameters are algorithm specific: not all algorithms support pre-trained
+dictionaries, not all algorithms support `level`. Furthermore, for certain
+algorithms `level` controls the compression level (the higher the value the
+better the compression ratio, it even can take negatives values for some
+algorithms), for other algorithms `level` is acceleration level (the higher
+the value the lower the compression ratio).
+
+5) Set Disksize
===============
Set disk size by writing the value to sysfs node 'disksize'.
@@ -125,7 +156,7 @@ There is little point creating a zram of greater than twice the size of memory
since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the
size of the disk when not in use so a huge zram is wasteful.
-5) Set memory limit: Optional
+6) Set memory limit: Optional
=============================
Set memory limit by writing the value to sysfs node 'mem_limit'.
@@ -144,7 +175,7 @@ Examples::
# To disable memory limit
echo 0 > /sys/block/zram0/mem_limit
-6) Activate
+7) Activate
===========
::
@@ -155,7 +186,7 @@ Examples::
mkfs.ext4 /dev/zram1
mount /dev/zram1 /tmp
-7) Add/remove zram devices
+8) Add/remove zram devices
==========================
zram provides a control interface, which enables dynamic (on-demand) device
@@ -175,7 +206,7 @@ execute::
echo X > /sys/class/zram-control/hot_remove
-8) Stats
+9) Stats
========
Per-device statistics are exported as various nodes under /sys/block/zram<id>/
@@ -277,7 +308,7 @@ a single line of text and contains the following stats separated by whitespace:
Unit: 4K bytes
============== =============================================================
-9) Deactivate
+10) Deactivate
=============
::
@@ -285,7 +316,7 @@ a single line of text and contains the following stats separated by whitespace:
swapoff /dev/zram0
umount /dev/zram1
-10) Reset
+11) Reset
=========
Write any positive value to 'reset' sysfs node::
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCHv7 24/24] zram: support priority parameter in recompression
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
` (22 preceding siblings ...)
2024-09-02 10:56 ` [PATCHv7 23/24] Documentation/zram: add documentation for algorithm parameters Sergey Senozhatsky
@ 2024-09-02 10:56 ` Sergey Senozhatsky
23 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-02 10:56 UTC (permalink / raw)
To: Andrew Morton; +Cc: Minchan Kim, linux-kernel, Sergey Senozhatsky
recompress device attribute supports alg=NAME parameter
so that we can specify only one particular algorithm we
want to perform recompression with. However, with algo
params we now can have several exactly same secondary
algorithms but each with its own params tuning (e.g.
priority 1 configured to use more aggressive level, and
priority 2 configured to use a pre-trained dictionary).
Support priority=NUM parameter so that we can correctly
determine which secondary algorithm we want to use.
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
Documentation/admin-guide/blockdev/zram.rst | 5 ++++-
drivers/block/zram/zram_drv.c | 12 ++++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst
index bb52d2fc0587..bbb1b1b8f10e 100644
--- a/Documentation/admin-guide/blockdev/zram.rst
+++ b/Documentation/admin-guide/blockdev/zram.rst
@@ -512,11 +512,14 @@ registered compression algorithms, increases our chances of finding the
algorithm that successfully compresses a particular page. Sometimes, however,
it is convenient (and sometimes even necessary) to limit recompression to
only one particular algorithm so that it will not try any other algorithms.
-This can be achieved by providing a algo=NAME parameter:::
+This can be achieved by providing a `algo` or `priority` parameter:::
#use zstd algorithm only (if registered)
echo "type=huge algo=zstd" > /sys/block/zramX/recompress
+ #use zstd algorithm only (if zstd was registered under priority 1)
+ echo "type=huge priority=1" > /sys/block/zramX/recompress
+
memory tracking
===============
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 9b29f9e6cb50..1f1bf175a6c3 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1855,6 +1855,18 @@ static ssize_t recompress_store(struct device *dev,
algo = val;
continue;
}
+
+ if (!strcmp(param, "priority")) {
+ ret = kstrtouint(val, 10, &prio);
+ if (ret)
+ return ret;
+
+ if (prio == ZRAM_PRIMARY_COMP)
+ prio = ZRAM_SECONDARY_COMP;
+
+ prio_max = min(prio + 1, ZRAM_MAX_COMPS);
+ continue;
+ }
}
if (threshold >= huge_class_size)
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH] Documentation/zram: trivial fixup
2024-09-02 10:56 ` [PATCHv7 23/24] Documentation/zram: add documentation for algorithm parameters Sergey Senozhatsky
@ 2024-09-03 6:37 ` Sergey Senozhatsky
0 siblings, 0 replies; 33+ messages in thread
From: Sergey Senozhatsky @ 2024-09-03 6:37 UTC (permalink / raw)
To: Andrew Morton; +Cc: Stephen Rothwell, linux-kernel, Sergey Senozhatsky
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
Documentation/admin-guide/blockdev/zram.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst
index bbb1b1b8f10e..678d70d6e1c3 100644
--- a/Documentation/admin-guide/blockdev/zram.rst
+++ b/Documentation/admin-guide/blockdev/zram.rst
@@ -309,7 +309,7 @@ a single line of text and contains the following stats separated by whitespace:
============== =============================================================
10) Deactivate
-=============
+==============
::
--
2.46.0.469.g59c65b2a67-goog
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCHv7 10/24] zram: add zlib compression backend support
2024-09-02 10:55 ` [PATCHv7 10/24] zram: add zlib compression backend support Sergey Senozhatsky
@ 2025-05-08 14:19 ` Zaslonko Mikhail
2025-05-09 1:38 ` Sergey Senozhatsky
0 siblings, 1 reply; 33+ messages in thread
From: Zaslonko Mikhail @ 2025-05-08 14:19 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Minchan Kim, linux-kernel, Andrew Morton, Ilya Leoshkevich,
Heiko Carstens, linux-s390
Hello Sergey,
On 02.09.2024 12:55, Sergey Senozhatsky wrote:
> Add s/w zlib (inflate/deflate) compression.
>
> Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
> ---
> diff --git a/drivers/block/zram/backend_deflate.c b/drivers/block/zram/backend_deflate.c
> new file mode 100644
> index 000000000000..acefb86701b9
> --- /dev/null
> +++ b/drivers/block/zram/backend_deflate.c
> @@ -0,0 +1,132 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/vmalloc.h>
> +#include <linux/zlib.h>
> +
> +#include "backend_deflate.h"
> +
> +/* Use the same value as crypto API */
> +#define DEFLATE_DEF_WINBITS 11
> +#define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL
> +
I was trying to use a zram device with a deflate compression algorithm tuned for s390 hardware acceleration. While I was able to set the compression level via algorithm_params sysfs attribute, I figured out that the window size used by zram zlib compression is limited to 4K since windowBits parameter is hardcoded to DEFLATE_DEF_WINBITS. In order to utilize s390 hardware deflate acceleration, the maximum window size is needed (windowBits of 15), which is also a zlib default. Thus, I'm wondering why windowBits value of 11 was picked for zram zlib compression backend support. The comment line says 'Use the same value as crypto API'... could you please clarify here? Are there some memory constraints?
I tried to build the kernel with DEFLATE_DEF_WINBITS set to 15 and verified that s390 hardware deflate acceleration works for zram devices with a deflate compression.
Thanks,
Mikhail
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCHv7 10/24] zram: add zlib compression backend support
2025-05-08 14:19 ` Zaslonko Mikhail
@ 2025-05-09 1:38 ` Sergey Senozhatsky
2025-05-09 15:18 ` Zaslonko Mikhail
0 siblings, 1 reply; 33+ messages in thread
From: Sergey Senozhatsky @ 2025-05-09 1:38 UTC (permalink / raw)
To: Zaslonko Mikhail
Cc: Sergey Senozhatsky, Minchan Kim, linux-kernel, Andrew Morton,
Ilya Leoshkevich, Heiko Carstens, linux-s390
Hello,
On (25/05/08 16:19), Zaslonko Mikhail wrote:
[..]
> > +#include "backend_deflate.h"
> > +
> > +/* Use the same value as crypto API */
> > +#define DEFLATE_DEF_WINBITS 11
> > +#define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL
> > +
[..]
> The comment line says 'Use the same value as crypto API'...
> could you please clarify here? Are there some memory constraints?
When zram transitioned from Crypto API (scomp) to custom compression
API I picked the CryptoAPI deflate DEFLATE_DEF_WINBITS value:
crypto/deflate.c: DEFLATE_DEF_WINBITS 11
which is then passed to zlib_deflateInit2() and zlib_inflateInit2().
> I tried to build the kernel with DEFLATE_DEF_WINBITS set to 15 and
> verified that s390 hardware deflate acceleration works for zram devices
> with a deflate compression.
If we define it as 15 on non-s390 machines, will there be any
consequences? Increased memory usage? By how much?
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCHv7 10/24] zram: add zlib compression backend support
2025-05-09 1:38 ` Sergey Senozhatsky
@ 2025-05-09 15:18 ` Zaslonko Mikhail
2025-05-13 5:41 ` Sergey Senozhatsky
0 siblings, 1 reply; 33+ messages in thread
From: Zaslonko Mikhail @ 2025-05-09 15:18 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Minchan Kim, linux-kernel, Andrew Morton, Ilya Leoshkevich,
Heiko Carstens, linux-s390
Hello,
On 09.05.2025 03:38, Sergey Senozhatsky wrote:
> Hello,
>
> On (25/05/08 16:19), Zaslonko Mikhail wrote:
> [..]
>>> +#include "backend_deflate.h"
>>> +
>>> +/* Use the same value as crypto API */
>>> +#define DEFLATE_DEF_WINBITS 11
>>> +#define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL
>>> +
> [..]
>> The comment line says 'Use the same value as crypto API'...
>> could you please clarify here? Are there some memory constraints?
>
> When zram transitioned from Crypto API (scomp) to custom compression
> API I picked the CryptoAPI deflate DEFLATE_DEF_WINBITS value:
>
> crypto/deflate.c: DEFLATE_DEF_WINBITS 11
>
> which is then passed to zlib_deflateInit2() and zlib_inflateInit2().
>
>> I tried to build the kernel with DEFLATE_DEF_WINBITS set to 15 and
>> verified that s390 hardware deflate acceleration works for zram devices
>> with a deflate compression.
>
> If we define it as 15 on non-s390 machines, will there be any
> consequences? Increased memory usage? By how much?
On s390, setting windowBits to 15 would lead to zlib workarea size
increased by 120K (0x24dc8 -> 0x42dc8) per compression stream,
i.e. per online CPU.
On non-s390 machine, that impact will be about 115K per stream.
Increasing window size should improve deflate compression,
although the compression speed might be affected. Couldn't find any
relevant zlib benchmarks though.
Not sure what other consequences might there be for zram. Do you see any?
>
Thanks,
Mikhail
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCHv7 10/24] zram: add zlib compression backend support
2025-05-09 15:18 ` Zaslonko Mikhail
@ 2025-05-13 5:41 ` Sergey Senozhatsky
2025-05-13 12:58 ` Zaslonko Mikhail
0 siblings, 1 reply; 33+ messages in thread
From: Sergey Senozhatsky @ 2025-05-13 5:41 UTC (permalink / raw)
To: Zaslonko Mikhail
Cc: Sergey Senozhatsky, Minchan Kim, linux-kernel, Andrew Morton,
Ilya Leoshkevich, Heiko Carstens, linux-s390
Sorry for the delay,
On (25/05/09 17:18), Zaslonko Mikhail wrote:
> > When zram transitioned from Crypto API (scomp) to custom compression
> > API I picked the CryptoAPI deflate DEFLATE_DEF_WINBITS value:
> >
> > crypto/deflate.c: DEFLATE_DEF_WINBITS 11
> >
> > which is then passed to zlib_deflateInit2() and zlib_inflateInit2().
> >
> >> I tried to build the kernel with DEFLATE_DEF_WINBITS set to 15 and
> >> verified that s390 hardware deflate acceleration works for zram devices
> >> with a deflate compression.
> >
> > If we define it as 15 on non-s390 machines, will there be any
> > consequences? Increased memory usage? By how much?
>
> On s390, setting windowBits to 15 would lead to zlib workarea size
> increased by 120K (0x24dc8 -> 0x42dc8) per compression stream,
> i.e. per online CPU.
> On non-s390 machine, that impact will be about 115K per stream.
> Increasing window size should improve deflate compression,
> although the compression speed might be affected. Couldn't find any
> relevant zlib benchmarks though.
>
> Not sure what other consequences might there be for zram. Do you see any?
The increased per-CPU memory usage is the only thing I can think of.
I guess for zram we could turn this into a run-time parameter, but for
Crypto API compile-time is the only option, I guess.
Can you send a patch series (for zram and Crypto API) that sets
windowBits to 15?
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCHv7 10/24] zram: add zlib compression backend support
2025-05-13 5:41 ` Sergey Senozhatsky
@ 2025-05-13 12:58 ` Zaslonko Mikhail
2025-05-14 2:56 ` Sergey Senozhatsky
0 siblings, 1 reply; 33+ messages in thread
From: Zaslonko Mikhail @ 2025-05-13 12:58 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Minchan Kim, linux-kernel, Andrew Morton, Ilya Leoshkevich,
Heiko Carstens, linux-s390
Hello,
On 13.05.2025 07:41, Sergey Senozhatsky wrote:
> Sorry for the delay,
>
> On (25/05/09 17:18), Zaslonko Mikhail wrote:
>>> When zram transitioned from Crypto API (scomp) to custom compression
>>> API I picked the CryptoAPI deflate DEFLATE_DEF_WINBITS value:
>>>
>>> crypto/deflate.c: DEFLATE_DEF_WINBITS 11
>>>
>>> which is then passed to zlib_deflateInit2() and zlib_inflateInit2().
>>>
>>>> I tried to build the kernel with DEFLATE_DEF_WINBITS set to 15 and
>>>> verified that s390 hardware deflate acceleration works for zram devices
>>>> with a deflate compression.
>>>
>>> If we define it as 15 on non-s390 machines, will there be any
>>> consequences? Increased memory usage? By how much?
>>
>> On s390, setting windowBits to 15 would lead to zlib workarea size
>> increased by 120K (0x24dc8 -> 0x42dc8) per compression stream,
>> i.e. per online CPU.
>> On non-s390 machine, that impact will be about 115K per stream.
>> Increasing window size should improve deflate compression,
>> although the compression speed might be affected. Couldn't find any
>> relevant zlib benchmarks though.
>>
>> Not sure what other consequences might there be for zram. Do you see any?
>
> The increased per-CPU memory usage is the only thing I can think of.
> I guess for zram we could turn this into a run-time parameter, but for
> Crypto API compile-time is the only option, I guess.
With 'run-time parameter' you mean adding 'windowBits' as another deflate compression
algorithm parameter for zram? Guess we could do this, using default value of 15 then.
>
> Can you send a patch series (for zram and Crypto API) that sets
> windowBits to 15?
I can do it for zram. Not sure if Crypto should be changed as well. Or is it
supposed to have the same compression defaults as zram?
Thanks,
Mikhail
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCHv7 10/24] zram: add zlib compression backend support
2025-05-13 12:58 ` Zaslonko Mikhail
@ 2025-05-14 2:56 ` Sergey Senozhatsky
2025-05-14 2:59 ` Herbert Xu
0 siblings, 1 reply; 33+ messages in thread
From: Sergey Senozhatsky @ 2025-05-14 2:56 UTC (permalink / raw)
To: Zaslonko Mikhail
Cc: Sergey Senozhatsky, Minchan Kim, linux-kernel, Andrew Morton,
Ilya Leoshkevich, Heiko Carstens, linux-s390, Herbert Xu
On (25/05/13 14:58), Zaslonko Mikhail wrote:
> On 13.05.2025 07:41, Sergey Senozhatsky wrote:
> > Sorry for the delay,
> >
> > On (25/05/09 17:18), Zaslonko Mikhail wrote:
> >>> When zram transitioned from Crypto API (scomp) to custom compression
> >>> API I picked the CryptoAPI deflate DEFLATE_DEF_WINBITS value:
> >>>
> >>> crypto/deflate.c: DEFLATE_DEF_WINBITS 11
> >>>
> >>> which is then passed to zlib_deflateInit2() and zlib_inflateInit2().
> >>>
> >>>> I tried to build the kernel with DEFLATE_DEF_WINBITS set to 15 and
> >>>> verified that s390 hardware deflate acceleration works for zram devices
> >>>> with a deflate compression.
> >>>
> >>> If we define it as 15 on non-s390 machines, will there be any
> >>> consequences? Increased memory usage? By how much?
> >>
> >> On s390, setting windowBits to 15 would lead to zlib workarea size
> >> increased by 120K (0x24dc8 -> 0x42dc8) per compression stream,
> >> i.e. per online CPU.
> >> On non-s390 machine, that impact will be about 115K per stream.
> >> Increasing window size should improve deflate compression,
> >> although the compression speed might be affected. Couldn't find any
> >> relevant zlib benchmarks though.
> >>
> >> Not sure what other consequences might there be for zram. Do you see any?
> >
> > The increased per-CPU memory usage is the only thing I can think of.
> > I guess for zram we could turn this into a run-time parameter, but for
> > Crypto API compile-time is the only option, I guess.
>
> With 'run-time parameter' you mean adding 'windowBits' as another deflate compression
> algorithm parameter for zram? Guess we could do this, using default value of 15 then.
I sent a simple patch set [1] that adds deflate.winbits parameter
support, so that it can be configured at runtime. E.g.:
echo "priority=1 deflate.winbits=15" > /sys/block/zram0/algorithm_params
Please take a look.
> > Can you send a patch series (for zram and Crypto API) that sets
> > windowBits to 15?
>
> I can do it for zram. Not sure if Crypto should be changed as well. Or is it
> supposed to have the same compression defaults as zram?
Crypto API uses a hard-coded value of -11, which wouldn't work in your
case. However, if you don't use crypto API (e.g. zswap) in your setup
then it probably doesn't need to be patched. Cc-ed Herbert from the
crypto API side, just in case.
[1] https://lore.kernel.org/linux-kernel/20250514024825.1745489-1-senozhatsky@chromium.org
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCHv7 10/24] zram: add zlib compression backend support
2025-05-14 2:56 ` Sergey Senozhatsky
@ 2025-05-14 2:59 ` Herbert Xu
0 siblings, 0 replies; 33+ messages in thread
From: Herbert Xu @ 2025-05-14 2:59 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Zaslonko Mikhail, Minchan Kim, linux-kernel, Andrew Morton,
Ilya Leoshkevich, Heiko Carstens, linux-s390, Cabiddu, Giovanni,
Linux Crypto Mailing List
On Wed, May 14, 2025 at 11:56:38AM +0900, Sergey Senozhatsky wrote:
>
> Crypto API uses a hard-coded value of -11, which wouldn't work in your
> case. However, if you don't use crypto API (e.g. zswap) in your setup
> then it probably doesn't need to be patched. Cc-ed Herbert from the
> crypto API side, just in case.
>
> [1] https://lore.kernel.org/linux-kernel/20250514024825.1745489-1-senozhatsky@chromium.org
Once we have parameter support in acomp you should be able to set
this as an optional parameter.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2025-05-14 3:00 UTC | newest]
Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-09-02 10:55 [PATCHv7 00/24] zram: introduce custom comp backends API Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 01/24] lib: zstd: export API needed for dictionary support Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 02/24] lib: lz4hc: export LZ4_resetStreamHC symbol Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 03/24] lib: zstd: fix null-deref in ZSTD_createCDict_advanced2() Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 04/24] zram: introduce custom comp backends API Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 05/24] zram: add lzo and lzorle compression backends support Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 06/24] zram: add lz4 compression backend support Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 07/24] zram: add lz4hc " Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 08/24] zram: add zstd " Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 09/24] zram: pass estimated src size hint to zstd Sergey Senozhatsky
2024-09-02 10:55 ` [PATCHv7 10/24] zram: add zlib compression backend support Sergey Senozhatsky
2025-05-08 14:19 ` Zaslonko Mikhail
2025-05-09 1:38 ` Sergey Senozhatsky
2025-05-09 15:18 ` Zaslonko Mikhail
2025-05-13 5:41 ` Sergey Senozhatsky
2025-05-13 12:58 ` Zaslonko Mikhail
2025-05-14 2:56 ` Sergey Senozhatsky
2025-05-14 2:59 ` Herbert Xu
2024-09-02 10:55 ` [PATCHv7 11/24] zram: add 842 " Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 12/24] zram: check that backends array has at least one backend Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 13/24] zram: introduce zcomp_params structure Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 14/24] zram: recalculate zstd compression params once Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 15/24] zram: introduce algorithm_params device attribute Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 16/24] zram: add support for dict comp config Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 17/24] zram: introduce zcomp_req structure Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 18/24] zram: introduce zcomp_ctx structure Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 19/24] zram: move immutable comp params away from per-CPU context Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 20/24] zram: add dictionary support to lz4 Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 21/24] zram: add dictionary support to lz4hc Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 22/24] zram: add dictionary support to zstd backend Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 23/24] Documentation/zram: add documentation for algorithm parameters Sergey Senozhatsky
2024-09-03 6:37 ` [PATCH] Documentation/zram: trivial fixup Sergey Senozhatsky
2024-09-02 10:56 ` [PATCHv7 24/24] zram: support priority parameter in recompression Sergey Senozhatsky
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®