Use LZ4_decompress_safe_usingDict() in lz4_decompress() and drop the per-CPU dstrm allocation. Store the compression workspace directly in ctx->context. Using vmalloc(LZ4_MEM_COMPRESS) instead of kzalloc() for cstrm and dict_stream when a dictionary is configured also avoids power-of-2 page rounding (~16 KB rounded up to 32 KB), saving ~12 KB per stream. Signed-off-by: Sergey Senozhatsky --- drivers/block/zram/backend_lz4.c | 76 ++++++-------------------------- 1 file changed, 14 insertions(+), 62 deletions(-) diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c index 158fd8b5e8a9..5f2e27805d75 100644 --- a/drivers/block/zram/backend_lz4.c +++ b/drivers/block/zram/backend_lz4.c @@ -4,18 +4,10 @@ #include #include -#include #include #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) { LZ4_stream_t *dict_stream = params->drv_data; @@ -24,7 +16,7 @@ static void lz4_release_params(struct zcomp_params *params) if (!dict_stream) return; - kfree(dict_stream); + vfree(dict_stream); } static int lz4_setup_params(struct zcomp_params *params) @@ -42,14 +34,14 @@ static int lz4_setup_params(struct zcomp_params *params) if (!params->dict || !params->dict_sz) return 0; - dict_stream = kzalloc_obj(*dict_stream); + dict_stream = vzalloc(sizeof(*dict_stream)); if (!dict_stream) return -ENOMEM; ret = LZ4_loadDict(dict_stream, params->dict, params->dict_sz); if (ret != params->dict_sz) { - kfree(dict_stream); + vfree(dict_stream); return -EINVAL; } params->drv_data = dict_stream; @@ -59,61 +51,32 @@ static int lz4_setup_params(struct zcomp_params *params) static void lz4_destroy(struct zcomp_ctx *ctx) { - struct lz4_ctx *zctx = ctx->context; - - if (!zctx) - return; - - vfree(zctx->mem); - kfree(zctx->dstrm); - kfree(zctx->cstrm); - kfree(zctx); + vfree(ctx->context); } static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx) { - struct lz4_ctx *zctx; + BUILD_BUG_ON(sizeof(LZ4_stream_t) != LZ4_MEM_COMPRESS); - zctx = kzalloc_obj(*zctx); - if (!zctx) + ctx->context = vmalloc(LZ4_MEM_COMPRESS); + if (!ctx->context) 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_obj(*zctx->dstrm); - if (!zctx->dstrm) - goto error; - - zctx->cstrm = kzalloc_obj(*zctx->cstrm); - 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; - if (!zctx->cstrm) { + if (!params->drv_data) { ret = LZ4_compress_fast(req->src, req->dst, req->src_len, req->dst_len, params->level, - zctx->mem); + ctx->context); } else { /* Cstrm needs to be reset */ - memcpy(zctx->cstrm, params->drv_data, sizeof(*zctx->cstrm)); - ret = LZ4_compress_fast_continue(zctx->cstrm, req->src, + memcpy(ctx->context, params->drv_data, sizeof(LZ4_stream_t)); + ret = LZ4_compress_fast_continue(ctx->context, req->src, req->dst, req->src_len, req->dst_len, params->level); } @@ -126,22 +89,11 @@ 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; - 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); - } + ret = LZ4_decompress_safe_usingDict(req->src, req->dst, req->src_len, + req->dst_len, params->dict, + params->dict_sz); if (ret < 0) return -EINVAL; return 0; -- 2.56.0.385.gd3acb90ef8-goog