Commit 70dd07c8 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

f2fs: use vmalloc instead of kvmalloc in .init_{,de}compress_ctx



.init_{,de}compress_ctx uses kvmalloc() to alloc memory, it will try
to allocate physically continuous page first, it may cause more memory
allocation pressure, let's use vmalloc instead to mitigate it.

[Test]
cd /data/local/tmp
touch file
f2fs_io setflags compression file
f2fs_io getflags file
for i in $(seq 1 10); do sync; echo 3 > /proc/sys/vm/drop_caches;\
time f2fs_io write 512 0 4096 zero osync file; truncate -s 0 file;\
done

[Result]
Before		After		Delta
21.243		21.694		-2.12%

For compression, we recommend to use ioctl to compress file data in
background for workaround.

For decompression, only zstd will be affected.

Signed-off-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 5827e3c7
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -180,8 +180,7 @@ void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct folio *folio)
#ifdef CONFIG_F2FS_FS_LZO
static int lzo_init_compress_ctx(struct compress_ctx *cc)
{
	cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode),
				LZO1X_MEM_COMPRESS, GFP_NOFS);
	cc->private = f2fs_vmalloc(LZO1X_MEM_COMPRESS);
	if (!cc->private)
		return -ENOMEM;

@@ -191,7 +190,7 @@ static int lzo_init_compress_ctx(struct compress_ctx *cc)

static void lzo_destroy_compress_ctx(struct compress_ctx *cc)
{
	kvfree(cc->private);
	vfree(cc->private);
	cc->private = NULL;
}

@@ -248,7 +247,7 @@ static int lz4_init_compress_ctx(struct compress_ctx *cc)
		size = LZ4HC_MEM_COMPRESS;
#endif

	cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), size, GFP_NOFS);
	cc->private = f2fs_vmalloc(size);
	if (!cc->private)
		return -ENOMEM;

@@ -263,7 +262,7 @@ static int lz4_init_compress_ctx(struct compress_ctx *cc)

static void lz4_destroy_compress_ctx(struct compress_ctx *cc)
{
	kvfree(cc->private);
	vfree(cc->private);
	cc->private = NULL;
}

@@ -344,8 +343,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
	params = zstd_get_params(level, cc->rlen);
	workspace_size = zstd_cstream_workspace_bound(&params.cParams);

	workspace = f2fs_kvmalloc(F2FS_I_SB(cc->inode),
					workspace_size, GFP_NOFS);
	workspace = f2fs_vmalloc(workspace_size);
	if (!workspace)
		return -ENOMEM;

@@ -353,7 +351,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
	if (!stream) {
		f2fs_err_ratelimited(F2FS_I_SB(cc->inode),
				"%s zstd_init_cstream failed", __func__);
		kvfree(workspace);
		vfree(workspace);
		return -EIO;
	}

@@ -366,7 +364,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)

static void zstd_destroy_compress_ctx(struct compress_ctx *cc)
{
	kvfree(cc->private);
	vfree(cc->private);
	cc->private = NULL;
	cc->private2 = NULL;
}
@@ -425,8 +423,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic)

	workspace_size = zstd_dstream_workspace_bound(max_window_size);

	workspace = f2fs_kvmalloc(F2FS_I_SB(dic->inode),
					workspace_size, GFP_NOFS);
	workspace = f2fs_vmalloc(workspace_size);
	if (!workspace)
		return -ENOMEM;

@@ -434,7 +431,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic)
	if (!stream) {
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
				"%s zstd_init_dstream failed", __func__);
		kvfree(workspace);
		vfree(workspace);
		return -EIO;
	}

@@ -446,7 +443,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic)

static void zstd_destroy_decompress_ctx(struct decompress_io_ctx *dic)
{
	kvfree(dic->private);
	vfree(dic->private);
	dic->private = NULL;
	dic->private2 = NULL;
}
+5 −0
Original line number Diff line number Diff line
@@ -3532,6 +3532,11 @@ static inline void *f2fs_kvzalloc(struct f2fs_sb_info *sbi,
	return f2fs_kvmalloc(sbi, size, flags | __GFP_ZERO);
}

static inline void *f2fs_vmalloc(size_t size)
{
	return vmalloc(size);
}

static inline int get_extra_isize(struct inode *inode)
{
	return F2FS_I(inode)->i_extra_isize / sizeof(__le32);