Skip to content

Commit 80eb4f6

Browse files
committed
erofs: avoid allocating DEFLATE streams before mounting
Currently, each DEFLATE stream takes one 32 KiB permanent internal window buffer even if there is no running instance which uses DEFLATE algorithm. It's unexpected and wasteful on embedded devices with limited resources and servers with hundreds of CPU cores if DEFLATE is enabled but unused. Fixes: ffa09b3 ("erofs: DEFLATE compression support") Cc: <[email protected]> # 6.6+ Reviewed-by: Sandeep Dhavale <[email protected]> Signed-off-by: Gao Xiang <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 5587a81 commit 80eb4f6

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

fs/erofs/decompressor_deflate.c

+29-26
Original file line numberDiff line numberDiff line change
@@ -46,39 +46,15 @@ int __init z_erofs_deflate_init(void)
4646
/* by default, use # of possible CPUs instead */
4747
if (!z_erofs_deflate_nstrms)
4848
z_erofs_deflate_nstrms = num_possible_cpus();
49-
50-
for (; z_erofs_deflate_avail_strms < z_erofs_deflate_nstrms;
51-
++z_erofs_deflate_avail_strms) {
52-
struct z_erofs_deflate *strm;
53-
54-
strm = kzalloc(sizeof(*strm), GFP_KERNEL);
55-
if (!strm)
56-
goto out_failed;
57-
58-
/* XXX: in-kernel zlib cannot shrink windowbits currently */
59-
strm->z.workspace = vmalloc(zlib_inflate_workspacesize());
60-
if (!strm->z.workspace) {
61-
kfree(strm);
62-
goto out_failed;
63-
}
64-
65-
spin_lock(&z_erofs_deflate_lock);
66-
strm->next = z_erofs_deflate_head;
67-
z_erofs_deflate_head = strm;
68-
spin_unlock(&z_erofs_deflate_lock);
69-
}
7049
return 0;
71-
72-
out_failed:
73-
erofs_err(NULL, "failed to allocate zlib workspace");
74-
z_erofs_deflate_exit();
75-
return -ENOMEM;
7650
}
7751

7852
int z_erofs_load_deflate_config(struct super_block *sb,
7953
struct erofs_super_block *dsb, void *data, int size)
8054
{
8155
struct z_erofs_deflate_cfgs *dfl = data;
56+
static DEFINE_MUTEX(deflate_resize_mutex);
57+
static bool inited;
8258

8359
if (!dfl || size < sizeof(struct z_erofs_deflate_cfgs)) {
8460
erofs_err(sb, "invalid deflate cfgs, size=%u", size);
@@ -89,9 +65,36 @@ int z_erofs_load_deflate_config(struct super_block *sb,
8965
erofs_err(sb, "unsupported windowbits %u", dfl->windowbits);
9066
return -EOPNOTSUPP;
9167
}
68+
mutex_lock(&deflate_resize_mutex);
69+
if (!inited) {
70+
for (; z_erofs_deflate_avail_strms < z_erofs_deflate_nstrms;
71+
++z_erofs_deflate_avail_strms) {
72+
struct z_erofs_deflate *strm;
73+
74+
strm = kzalloc(sizeof(*strm), GFP_KERNEL);
75+
if (!strm)
76+
goto failed;
77+
/* XXX: in-kernel zlib cannot customize windowbits */
78+
strm->z.workspace = vmalloc(zlib_inflate_workspacesize());
79+
if (!strm->z.workspace) {
80+
kfree(strm);
81+
goto failed;
82+
}
9283

84+
spin_lock(&z_erofs_deflate_lock);
85+
strm->next = z_erofs_deflate_head;
86+
z_erofs_deflate_head = strm;
87+
spin_unlock(&z_erofs_deflate_lock);
88+
}
89+
inited = true;
90+
}
91+
mutex_unlock(&deflate_resize_mutex);
9392
erofs_info(sb, "EXPERIMENTAL DEFLATE feature in use. Use at your own risk!");
9493
return 0;
94+
failed:
95+
mutex_unlock(&deflate_resize_mutex);
96+
z_erofs_deflate_exit();
97+
return -ENOMEM;
9598
}
9699

97100
int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,

0 commit comments

Comments
 (0)