2024-05-30 09:23:38

by Gao Xiang

[permalink] [raw]
Subject: [PATCH 6.9.y] erofs: avoid allocating DEFLATE streams before mounting

commit 80eb4f62056d6ae709bdd0636ab96ce660f494b2 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: ffa09b3bd024 ("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]
---
fs/erofs/decompressor_deflate.c | 55 +++++++++++++++++----------------
1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c
index 81e65c453ef0..3a3461561a3c 100644
--- a/fs/erofs/decompressor_deflate.c
+++ b/fs/erofs/decompressor_deflate.c
@@ -46,39 +46,15 @@ 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:
- erofs_err(NULL, "failed to allocate zlib workspace");
- z_erofs_deflate_exit();
- return -ENOMEM;
}

int z_erofs_load_deflate_config(struct super_block *sb,
struct erofs_super_block *dsb, void *data, int size)
{
struct z_erofs_deflate_cfgs *dfl = data;
+ 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);
@@ -89,9 +65,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,
--
2.39.3



2024-05-30 09:24:17

by Gao Xiang

[permalink] [raw]
Subject: [PATCH 6.8.y] erofs: avoid allocating DEFLATE streams before mounting

commit 80eb4f62056d6ae709bdd0636ab96ce660f494b2 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: ffa09b3bd024 ("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]
---
fs/erofs/decompressor_deflate.c | 55 +++++++++++++++++----------------
1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c
index b98872058abe..26350c5b040e 100644
--- a/fs/erofs/decompressor_deflate.c
+++ b/fs/erofs/decompressor_deflate.c
@@ -46,39 +46,15 @@ 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:
- erofs_err(NULL, "failed to allocate zlib workspace");
- z_erofs_deflate_exit();
- return -ENOMEM;
}

int z_erofs_load_deflate_config(struct super_block *sb,
struct erofs_super_block *dsb, void *data, int size)
{
struct z_erofs_deflate_cfgs *dfl = data;
+ 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);
@@ -89,9 +65,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,
--
2.39.3


2024-05-30 09:31:28

by Gao Xiang

[permalink] [raw]
Subject: [PATCH 6.6.y] erofs: avoid allocating DEFLATE streams before mounting

commit 80eb4f62056d6ae709bdd0636ab96ce660f494b2 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: ffa09b3bd024 ("erofs: DEFLATE compression support")
Cc: <[email protected]> # 6.6+
Reviewed-by: Sandeep Dhavale <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
[ Gao Xiang: resolve trivial conflicts. ]
Signed-off-by: Gao Xiang <[email protected]>
---
fs/erofs/decompressor_deflate.c | 55 +++++++++++++++++----------------
1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c
index 0e1946a6bda5..aac2c837ef35 100644
--- a/fs/erofs/decompressor_deflate.c
+++ b/fs/erofs/decompressor_deflate.c
@@ -47,39 +47,15 @@ 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, void *data, int size)
{
struct z_erofs_deflate_cfgs *dfl = data;
+ 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);
@@ -90,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,
--
2.39.3


2024-06-04 12:46:13

by Gao Xiang

[permalink] [raw]
Subject: Re: [PATCH 6.9.y] erofs: avoid allocating DEFLATE streams before mounting

Hi Greg,

ping? Do these backport fixes miss the 6.6, 6.8, 6.9 queues..

Thanks,
Gao XIang

On 2024/5/30 17:21, Gao Xiang wrote:
> commit 80eb4f62056d6ae709bdd0636ab96ce660f494b2 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: ffa09b3bd024 ("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]
> ---
> fs/erofs/decompressor_deflate.c | 55 +++++++++++++++++----------------
> 1 file changed, 29 insertions(+), 26 deletions(-)
>
> diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c
> index 81e65c453ef0..3a3461561a3c 100644
> --- a/fs/erofs/decompressor_deflate.c
> +++ b/fs/erofs/decompressor_deflate.c
> @@ -46,39 +46,15 @@ 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:
> - erofs_err(NULL, "failed to allocate zlib workspace");
> - z_erofs_deflate_exit();
> - return -ENOMEM;
> }
>
> int z_erofs_load_deflate_config(struct super_block *sb,
> struct erofs_super_block *dsb, void *data, int size)
> {
> struct z_erofs_deflate_cfgs *dfl = data;
> + 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);
> @@ -89,9 +65,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,

2024-06-12 12:59:06

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 6.9.y] erofs: avoid allocating DEFLATE streams before mounting

On Tue, Jun 04, 2024 at 08:33:05PM +0800, Gao Xiang wrote:
> Hi Greg,
>
> ping? Do these backport fixes miss the 6.6, 6.8, 6.9 queues..

Sorry for the delay, all now queued up.

well, except for 6.8.y, that branch is now end-of-life, sorry.

greg k-h

2024-06-12 14:26:12

by Gao Xiang

[permalink] [raw]
Subject: Re: [PATCH 6.9.y] erofs: avoid allocating DEFLATE streams before mounting



On 2024/6/12 20:54, Greg Kroah-Hartman wrote:
> On Tue, Jun 04, 2024 at 08:33:05PM +0800, Gao Xiang wrote:
>> Hi Greg,
>>
>> ping? Do these backport fixes miss the 6.6, 6.8, 6.9 queues..
>
> Sorry for the delay, all now queued up.
>
> well, except for 6.8.y, that branch is now end-of-life, sorry.

Thanks Greg!

Thanks,
Gao Xiang

>
> greg k-h