btrfs: use kvmalloc() to allocate compression workspace buffer for zlib and zstd

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.

Reviewed-by: Daniel Vacek <neelx@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Qu Wenruo 2026-09-08 16:45:41 +09:30 committed by David Sterba
parent 883a1a260c
commit 0f2cb9a9e9
2 changed files with 7 additions and 7 deletions

View File

@ -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)

View File

@ -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;