Re: [PATCH 07/10] zram: zstd: do not use kvzalloc() for zstd allocations

From: Brian Geffon

Date: Tue Oct 06 2026 - 02:31:56 EST


On Mon, Oct 5, 2026 at 9:21 PM Sergey Senozhatsky
<senozhatsky@xxxxxxxxxxxx> wrote:
>
> When a dictionary is configured, zstd allocates all of its memory (C/D
> dictionaries, compression and decompression contexts and compression
> workspaces) via zstd_custom_alloc(). zstd_custom_alloc() uses
> kvzalloc(), which falls back to vmalloc() only when kmalloc() fails,
> and kmalloc() rounds such sizes up to a power-of-two number of pages.
>
> For example, on x86_64 with a 110K dictionary, switching from
> kvzalloc() to __vmalloc() reduces allocations from:
> - CDict (level 3): 512 KB -> 400 KB
> - CDict (levels 12+): 2048 KB -> 1552 KB
> - DCtx (per-CPU): 128 KB -> 96 KB
> - CCtx workspace (level 3): 128 KB -> 84 KB (per-CPU)
> - CCtx workspace (level 14+): 1024 KB -> 764 KB (per-CPU)
>
> Use __vmalloc() for allocations larger than PAGE_SIZE (and kzalloc()
> for smaller ones), which is also how zram allocates zstd workspaces
> when no dictionary is configured. zstd_custom_free() already uses
> kvfree(), which handles both.
>
> Signed-off-by: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx>

Acked-by: Brian Geffon <bgeffon@xxxxxxxxxx>

> ---
> drivers/block/zram/backend_zstd.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
> index b367049f131d..7a8b5ff186f2 100644
> --- a/drivers/block/zram/backend_zstd.c
> +++ b/drivers/block/zram/backend_zstd.c
> @@ -26,10 +26,17 @@ struct zstd_params {
> /*
> * For C/D dictionaries we need to provide zstd with zstd_custom_mem,
> * which zstd uses internally to allocate/free memory when needed.
> + *
> + * zstd allocations (C/D dictionaries and contexts) are large and
> + * long-lived. Don't use kvzalloc() for them: when enough physically
> + * contiguous memory is available it serves them from kmalloc(), which
> + * rounds them up to a power-of-two number of pages.
> */
> static void *zstd_custom_alloc(void *opaque, size_t size)
> {
> - return kvzalloc(size, GFP_NOIO | __GFP_NOWARN);
> + if (size <= PAGE_SIZE)
> + return kzalloc(size, GFP_NOIO | __GFP_NOWARN);
> + return __vmalloc(size, GFP_NOIO | __GFP_NOWARN | __GFP_ZERO);
> }
>
> static void zstd_custom_free(void *opaque, void *address)
> --
> 2.56.0.rc1.315.gc6ed9934b7-goog
>