Thread (9 messages) flat view 9 messages, 4 authors, 4d ago

Re: [PATCH 3/3] btrfs: use kvmalloc() to allocate compression workspace buffer

From: Daniel Vacek <hidden>
Date: 2026-09-08 07:39:03

On Tue, 8 Sept 2026 at 09:35, Qu Wenruo [off-list ref] wrote:
With the experimental bs > ps support, the workspace buffer for both
zlib and zstd can be as large as 64K, and on 4K page sized systems such
kmalloc() calls have a much higher chance to fail, as that requires
physically contiguous memory to fulfill such allocation.

The same also applies to S390's hardware accelerated path, which
requires a buffer size of 4 pages.

Meanwhile lzo is already using kvmalloc() for its buffer, and there is
no special requirement for any physically contiguous memory anyway.

So change the zlib and zstd workspace buffer allocation to use
kvmalloc() to reduce the chance of memory allocation failure.

Signed-off-by: Qu Wenruo <redacted>
LGTM

Reviewed-by: Daniel Vacek <redacted>
quoted hunk ↗ jump to hunk
---
 fs/btrfs/zlib.c | 10 +++++-----
 fs/btrfs/zstd.c |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c
index 486b52db583e..e995d0b1452b 100644
--- a/fs/btrfs/zlib.c
+++ b/fs/btrfs/zlib.c
@@ -49,7 +49,7 @@ void zlib_free_workspace(struct list_head *ws)
        struct workspace *workspace = list_entry(ws, struct workspace, list);

        kvfree(workspace->strm.workspace);
-       kfree(workspace->buf);
+       kvfree(workspace->buf);
        kfree(workspace);
 }
@@ -84,13 +84,13 @@ struct list_head *zlib_alloc_workspace(struct btrfs_fs_info *fs_info, unsigned i
        workspace->level = level;
        workspace->buf = NULL;
        if (need_special_buffer(fs_info)) {
-               workspace->buf = kmalloc(ZLIB_DFLTCC_BUF_SIZE,
-                                        __GFP_NOMEMALLOC | __GFP_NORETRY |
-                                        __GFP_NOWARN | GFP_NOIO);
+               workspace->buf = kvmalloc(ZLIB_DFLTCC_BUF_SIZE,
+                                         __GFP_NOMEMALLOC | __GFP_NORETRY |
+                                         __GFP_NOWARN | GFP_NOIO);
                workspace->buf_size = ZLIB_DFLTCC_BUF_SIZE;
        }
        if (!workspace->buf) {
-               workspace->buf = kmalloc(fs_info->sectorsize, GFP_KERNEL);
+               workspace->buf = kvmalloc(fs_info->sectorsize, GFP_KERNEL);
                workspace->buf_size = fs_info->sectorsize;
        }
        if (!workspace->strm.workspace || !workspace->buf)
diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c
index 280ac5273438..cc92d0b1b948 100644
--- a/fs/btrfs/zstd.c
+++ b/fs/btrfs/zstd.c
@@ -373,7 +373,7 @@ void zstd_free_workspace(struct list_head *ws)
        struct workspace *workspace = list_entry(ws, struct workspace, list);

        kvfree(workspace->mem);
-       kfree(workspace->buf);
+       kvfree(workspace->buf);
        kfree(workspace);
 }
@@ -391,7 +391,7 @@ struct list_head *zstd_alloc_workspace(struct btrfs_fs_info *fs_info, int level)
        workspace->req_level = level;
        workspace->last_used = jiffies;
        workspace->mem = kvmalloc(workspace->size, GFP_KERNEL | __GFP_NOWARN);
-       workspace->buf = kmalloc(fs_info->sectorsize, GFP_KERNEL);
+       workspace->buf = kvmalloc(fs_info->sectorsize, GFP_KERNEL);
        if (!workspace->mem || !workspace->buf)
                goto fail;

--
2.55.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help