erofs: avoid allocating DEFLATE streams before mounting
ANBZ: #9242 commit80eb4f6205
upstream 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:ffa09b3bd0
("erofs: DEFLATE compression support") Cc: <stable@vger.kernel.org> # 6.6+ Reviewed-by: Sandeep Dhavale <dhavale@google.com> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20240520090106.2898681-1-hsiangkao@linux.alibaba.com Signed-off-by: Hongzhen Luo <hongzhen@linux.alibaba.com> Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com> Link: https://gitee.com/anolis/cloud-kernel/pulls/3281
This commit is contained in:
parent
c01e8ac00d
commit
23b3b1f886
|
@ -47,39 +47,16 @@ int __init z_erofs_deflate_init(void)
|
|||
/* by default, use # of possible CPUs instead */
|
||||
if (!z_erofs_deflate_nstrms)
|
||||
z_erofs_deflate_nstrms = num_possible_cpus();
|
||||
|
||||
for (; z_erofs_deflate_avail_strms < z_erofs_deflate_nstrms;
|
||||
++z_erofs_deflate_avail_strms) {
|
||||
struct z_erofs_deflate *strm;
|
||||
|
||||
strm = kzalloc(sizeof(*strm), GFP_KERNEL);
|
||||
if (!strm)
|
||||
goto out_failed;
|
||||
|
||||
/* XXX: in-kernel zlib cannot shrink windowbits currently */
|
||||
strm->z.workspace = vmalloc(zlib_inflate_workspacesize());
|
||||
if (!strm->z.workspace) {
|
||||
kfree(strm);
|
||||
goto out_failed;
|
||||
}
|
||||
|
||||
spin_lock(&z_erofs_deflate_lock);
|
||||
strm->next = z_erofs_deflate_head;
|
||||
z_erofs_deflate_head = strm;
|
||||
spin_unlock(&z_erofs_deflate_lock);
|
||||
}
|
||||
return 0;
|
||||
|
||||
out_failed:
|
||||
pr_err("failed to allocate zlib workspace\n");
|
||||
z_erofs_deflate_exit();
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int z_erofs_load_deflate_config(struct super_block *sb,
|
||||
struct erofs_super_block *dsb,
|
||||
struct z_erofs_deflate_cfgs *dfl, int size)
|
||||
{
|
||||
static DEFINE_MUTEX(deflate_resize_mutex);
|
||||
static bool inited;
|
||||
|
||||
if (!dfl || size < sizeof(struct z_erofs_deflate_cfgs)) {
|
||||
erofs_err(sb, "invalid deflate cfgs, size=%u", size);
|
||||
return -EINVAL;
|
||||
|
@ -89,9 +66,36 @@ int z_erofs_load_deflate_config(struct super_block *sb,
|
|||
erofs_err(sb, "unsupported windowbits %u", dfl->windowbits);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
mutex_lock(&deflate_resize_mutex);
|
||||
if (!inited) {
|
||||
for (; z_erofs_deflate_avail_strms < z_erofs_deflate_nstrms;
|
||||
++z_erofs_deflate_avail_strms) {
|
||||
struct z_erofs_deflate *strm;
|
||||
|
||||
strm = kzalloc(sizeof(*strm), GFP_KERNEL);
|
||||
if (!strm)
|
||||
goto failed;
|
||||
/* XXX: in-kernel zlib cannot customize windowbits */
|
||||
strm->z.workspace = vmalloc(zlib_inflate_workspacesize());
|
||||
if (!strm->z.workspace) {
|
||||
kfree(strm);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
spin_lock(&z_erofs_deflate_lock);
|
||||
strm->next = z_erofs_deflate_head;
|
||||
z_erofs_deflate_head = strm;
|
||||
spin_unlock(&z_erofs_deflate_lock);
|
||||
}
|
||||
inited = true;
|
||||
}
|
||||
mutex_unlock(&deflate_resize_mutex);
|
||||
erofs_info(sb, "EXPERIMENTAL DEFLATE feature in use. Use at your own risk!");
|
||||
return 0;
|
||||
failed:
|
||||
mutex_unlock(&deflate_resize_mutex);
|
||||
z_erofs_deflate_exit();
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
|
||||
|
|
Loading…
Reference in New Issue