The quilt patch titled Subject: zram: introduce zcomp_ctx structure has been removed from the -mm tree. Its filename was zram-introduce-zcomp_ctx-structure.patch This patch was dropped because it was merged into the mm-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm ------------------------------------------------------ From: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx> Subject: zram: introduce zcomp_ctx structure Date: Mon, 2 Sep 2024 19:56:06 +0900 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. Link: https://lkml.kernel.org/r/20240902105656.1383858-19-senozhatsky@xxxxxxxxxxxx Signed-off-by: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx> Cc: Minchan Kim <minchan@xxxxxxxxxx> Cc: Nick Terrell <terrelln@xxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- 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(-) --- a/drivers/block/zram/backend_842.c~zram-introduce-zcomp_ctx-structure +++ a/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; --- a/drivers/block/zram/backend_deflate.c~zram-introduce-zcomp_ctx-structure +++ a/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, s 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; --- a/drivers/block/zram/backend_lz4.c~zram-introduce-zcomp_ctx-structure +++ a/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, struc 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; --- a/drivers/block/zram/backend_lz4hc.c~zram-introduce-zcomp_ctx-structure +++ a/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, str 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; --- a/drivers/block/zram/backend_lzo.c~zram-introduce-zcomp_ctx-structure +++ a/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; --- a/drivers/block/zram/backend_lzorle.c~zram-introduce-zcomp_ctx-structure +++ a/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; --- a/drivers/block/zram/backend_zstd.c~zram-introduce-zcomp_ctx-structure +++ a/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, stru 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, --- a/drivers/block/zram/zcomp.c~zram-introduce-zcomp_ctx-structure +++ a/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, s }; 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, .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) --- a/drivers/block/zram/zcomp.h~zram-introduce-zcomp_ctx-structure +++ a/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; }; _ Patches currently in -mm which might be from senozhatsky@xxxxxxxxxxxx are zsmalloc-use-unique-zsmalloc-caches-names.patch