All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] erofs: support adjust lz4 history window size
@ 2021-02-23  7:31 ` Huang Jianan via Linux-erofs
  0 siblings, 0 replies; 6+ messages in thread
From: Huang Jianan @ 2021-02-23  7:31 UTC (permalink / raw)
  To: linux-erofs; +Cc: huangjianan, guoweichao, zhangshiming, linux-kernel

lz4 uses LZ4_DISTANCE_MAX to record history preservation. When
using rolling decompression, a block with a higher compression
ratio will cause a larger memory allocation (up to 64k). It may
cause a large resource burden in extreme cases on devices with
small memory and a large number of concurrent IOs. So appropriately
reducing this value can improve performance.

Decreasing this value will reduce the compression ratio (except
when input_size <LZ4_DISTANCE_MAX). But considering that erofs
currently only supports 4k output, reducing this value will not
significantly reduce the compression benefits.

The maximum value of LZ4_DISTANCE_MAX defined by lz4 is 64k, and
we can only reduce this value. For the old kernel, it just can't
reduce the memory allocation during rolling decompression without
affecting the decompression result.

Signed-off-by: Huang Jianan <huangjianan@oppo.com>
Signed-off-by: Guo Weichao <guoweichao@oppo.com>
---

change since v2:
- use z_erofs_load_lz4_config to calculate lz4_distance_pages
- add description about the compatibility of the old kernel version
- drop useless comment

 fs/erofs/decompressor.c | 22 ++++++++++++++++++----
 fs/erofs/erofs_fs.h     |  3 ++-
 fs/erofs/internal.h     |  7 +++++++
 fs/erofs/super.c        |  2 ++
 4 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
index 1cb1ffd10569..0bb7903e3f9b 100644
--- a/fs/erofs/decompressor.c
+++ b/fs/erofs/decompressor.c
@@ -28,6 +28,18 @@ struct z_erofs_decompressor {
 	char *name;
 };
 
+int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
+			    struct erofs_super_block *dsb)
+{
+	u16 distance = le16_to_cpu(dsb->lz4_max_distance);
+
+	sbi->lz4_max_distance_pages = distance ?
+					(DIV_ROUND_UP(distance, PAGE_SIZE) + 1) :
+					LZ4_MAX_DISTANCE_PAGES;
+
+	return 0;
+}
+
 static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq,
 					 struct list_head *pagepool)
 {
@@ -36,6 +48,8 @@ static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq,
 	struct page *availables[LZ4_MAX_DISTANCE_PAGES] = { NULL };
 	unsigned long bounced[DIV_ROUND_UP(LZ4_MAX_DISTANCE_PAGES,
 					   BITS_PER_LONG)] = { 0 };
+	unsigned int lz4_max_distance_pages =
+				EROFS_SB(rq->sb)->lz4_max_distance_pages;
 	void *kaddr = NULL;
 	unsigned int i, j, top;
 
@@ -44,14 +58,14 @@ static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq,
 		struct page *const page = rq->out[i];
 		struct page *victim;
 
-		if (j >= LZ4_MAX_DISTANCE_PAGES)
+		if (j >= lz4_max_distance_pages)
 			j = 0;
 
 		/* 'valid' bounced can only be tested after a complete round */
 		if (test_bit(j, bounced)) {
-			DBG_BUGON(i < LZ4_MAX_DISTANCE_PAGES);
-			DBG_BUGON(top >= LZ4_MAX_DISTANCE_PAGES);
-			availables[top++] = rq->out[i - LZ4_MAX_DISTANCE_PAGES];
+			DBG_BUGON(i < lz4_max_distance_pages);
+			DBG_BUGON(top >= lz4_max_distance_pages);
+			availables[top++] = rq->out[i - lz4_max_distance_pages];
 		}
 
 		if (page) {
diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h
index 9ad1615f4474..b27d0e4e4ab5 100644
--- a/fs/erofs/erofs_fs.h
+++ b/fs/erofs/erofs_fs.h
@@ -39,7 +39,8 @@ struct erofs_super_block {
 	__u8 uuid[16];          /* 128-bit uuid for volume */
 	__u8 volume_name[16];   /* volume name */
 	__le32 feature_incompat;
-	__u8 reserved2[44];
+	__le16 lz4_max_distance;
+	__u8 reserved2[42];
 };
 
 /*
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 67a7ec945686..4cb2395db45c 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -70,6 +70,9 @@ struct erofs_sb_info {
 
 	/* pseudo inode to manage cached pages */
 	struct inode *managed_cache;
+
+	/* # of pages needed for EROFS lz4 rolling decompression */
+	u16 lz4_max_distance_pages;
 #endif	/* CONFIG_EROFS_FS_ZIP */
 	u32 blocks;
 	u32 meta_blkaddr;
@@ -420,6 +423,8 @@ int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi,
 				       struct erofs_workgroup *egrp);
 int erofs_try_to_free_cached_page(struct address_space *mapping,
 				  struct page *page);
+int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
+			    struct erofs_super_block *dsb);
 #else
 static inline void erofs_shrinker_register(struct super_block *sb) {}
 static inline void erofs_shrinker_unregister(struct super_block *sb) {}
@@ -427,6 +432,8 @@ static inline int erofs_init_shrinker(void) { return 0; }
 static inline void erofs_exit_shrinker(void) {}
 static inline int z_erofs_init_zip_subsystem(void) { return 0; }
 static inline void z_erofs_exit_zip_subsystem(void) {}
+static inline int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
+					  struct erofs_super_block *dsb) { return 0; }
 #endif	/* !CONFIG_EROFS_FS_ZIP */
 
 #define EFSCORRUPTED    EUCLEAN         /* Filesystem is corrupted */
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index d5a6b9b888a5..11bc51e488dd 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -166,6 +166,8 @@ static int erofs_read_superblock(struct super_block *sb)
 	if (!check_layout_compatibility(sb, dsb))
 		goto out;
 
+	z_erofs_load_lz4_config(sbi, dsb);
+
 	sbi->blocks = le32_to_cpu(dsb->blocks);
 	sbi->meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
 #ifdef CONFIG_EROFS_FS_XATTR
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3] erofs: support adjust lz4 history window size
@ 2021-02-23  7:31 ` Huang Jianan via Linux-erofs
  0 siblings, 0 replies; 6+ messages in thread
From: Huang Jianan via Linux-erofs @ 2021-02-23  7:31 UTC (permalink / raw)
  To: linux-erofs; +Cc: linux-kernel, guoweichao, zhangshiming

lz4 uses LZ4_DISTANCE_MAX to record history preservation. When
using rolling decompression, a block with a higher compression
ratio will cause a larger memory allocation (up to 64k). It may
cause a large resource burden in extreme cases on devices with
small memory and a large number of concurrent IOs. So appropriately
reducing this value can improve performance.

Decreasing this value will reduce the compression ratio (except
when input_size <LZ4_DISTANCE_MAX). But considering that erofs
currently only supports 4k output, reducing this value will not
significantly reduce the compression benefits.

The maximum value of LZ4_DISTANCE_MAX defined by lz4 is 64k, and
we can only reduce this value. For the old kernel, it just can't
reduce the memory allocation during rolling decompression without
affecting the decompression result.

Signed-off-by: Huang Jianan <huangjianan@oppo.com>
Signed-off-by: Guo Weichao <guoweichao@oppo.com>
---

change since v2:
- use z_erofs_load_lz4_config to calculate lz4_distance_pages
- add description about the compatibility of the old kernel version
- drop useless comment

 fs/erofs/decompressor.c | 22 ++++++++++++++++++----
 fs/erofs/erofs_fs.h     |  3 ++-
 fs/erofs/internal.h     |  7 +++++++
 fs/erofs/super.c        |  2 ++
 4 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
index 1cb1ffd10569..0bb7903e3f9b 100644
--- a/fs/erofs/decompressor.c
+++ b/fs/erofs/decompressor.c
@@ -28,6 +28,18 @@ struct z_erofs_decompressor {
 	char *name;
 };
 
+int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
+			    struct erofs_super_block *dsb)
+{
+	u16 distance = le16_to_cpu(dsb->lz4_max_distance);
+
+	sbi->lz4_max_distance_pages = distance ?
+					(DIV_ROUND_UP(distance, PAGE_SIZE) + 1) :
+					LZ4_MAX_DISTANCE_PAGES;
+
+	return 0;
+}
+
 static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq,
 					 struct list_head *pagepool)
 {
@@ -36,6 +48,8 @@ static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq,
 	struct page *availables[LZ4_MAX_DISTANCE_PAGES] = { NULL };
 	unsigned long bounced[DIV_ROUND_UP(LZ4_MAX_DISTANCE_PAGES,
 					   BITS_PER_LONG)] = { 0 };
+	unsigned int lz4_max_distance_pages =
+				EROFS_SB(rq->sb)->lz4_max_distance_pages;
 	void *kaddr = NULL;
 	unsigned int i, j, top;
 
@@ -44,14 +58,14 @@ static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq,
 		struct page *const page = rq->out[i];
 		struct page *victim;
 
-		if (j >= LZ4_MAX_DISTANCE_PAGES)
+		if (j >= lz4_max_distance_pages)
 			j = 0;
 
 		/* 'valid' bounced can only be tested after a complete round */
 		if (test_bit(j, bounced)) {
-			DBG_BUGON(i < LZ4_MAX_DISTANCE_PAGES);
-			DBG_BUGON(top >= LZ4_MAX_DISTANCE_PAGES);
-			availables[top++] = rq->out[i - LZ4_MAX_DISTANCE_PAGES];
+			DBG_BUGON(i < lz4_max_distance_pages);
+			DBG_BUGON(top >= lz4_max_distance_pages);
+			availables[top++] = rq->out[i - lz4_max_distance_pages];
 		}
 
 		if (page) {
diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h
index 9ad1615f4474..b27d0e4e4ab5 100644
--- a/fs/erofs/erofs_fs.h
+++ b/fs/erofs/erofs_fs.h
@@ -39,7 +39,8 @@ struct erofs_super_block {
 	__u8 uuid[16];          /* 128-bit uuid for volume */
 	__u8 volume_name[16];   /* volume name */
 	__le32 feature_incompat;
-	__u8 reserved2[44];
+	__le16 lz4_max_distance;
+	__u8 reserved2[42];
 };
 
 /*
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 67a7ec945686..4cb2395db45c 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -70,6 +70,9 @@ struct erofs_sb_info {
 
 	/* pseudo inode to manage cached pages */
 	struct inode *managed_cache;
+
+	/* # of pages needed for EROFS lz4 rolling decompression */
+	u16 lz4_max_distance_pages;
 #endif	/* CONFIG_EROFS_FS_ZIP */
 	u32 blocks;
 	u32 meta_blkaddr;
@@ -420,6 +423,8 @@ int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi,
 				       struct erofs_workgroup *egrp);
 int erofs_try_to_free_cached_page(struct address_space *mapping,
 				  struct page *page);
+int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
+			    struct erofs_super_block *dsb);
 #else
 static inline void erofs_shrinker_register(struct super_block *sb) {}
 static inline void erofs_shrinker_unregister(struct super_block *sb) {}
@@ -427,6 +432,8 @@ static inline int erofs_init_shrinker(void) { return 0; }
 static inline void erofs_exit_shrinker(void) {}
 static inline int z_erofs_init_zip_subsystem(void) { return 0; }
 static inline void z_erofs_exit_zip_subsystem(void) {}
+static inline int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
+					  struct erofs_super_block *dsb) { return 0; }
 #endif	/* !CONFIG_EROFS_FS_ZIP */
 
 #define EFSCORRUPTED    EUCLEAN         /* Filesystem is corrupted */
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index d5a6b9b888a5..11bc51e488dd 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -166,6 +166,8 @@ static int erofs_read_superblock(struct super_block *sb)
 	if (!check_layout_compatibility(sb, dsb))
 		goto out;
 
+	z_erofs_load_lz4_config(sbi, dsb);
+
 	sbi->blocks = le32_to_cpu(dsb->blocks);
 	sbi->meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
 #ifdef CONFIG_EROFS_FS_XATTR
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] erofs: support adjust lz4 history window size
  2021-02-23  7:31 ` Huang Jianan via Linux-erofs
@ 2021-02-23  7:44   ` Gao Xiang
  -1 siblings, 0 replies; 6+ messages in thread
From: Gao Xiang @ 2021-02-23  7:44 UTC (permalink / raw)
  To: Huang Jianan; +Cc: linux-erofs, linux-kernel, guoweichao, zhangshiming

On Tue, Feb 23, 2021 at 03:31:19PM +0800, Huang Jianan via Linux-erofs wrote:
> lz4 uses LZ4_DISTANCE_MAX to record history preservation. When
> using rolling decompression, a block with a higher compression
> ratio will cause a larger memory allocation (up to 64k). It may
> cause a large resource burden in extreme cases on devices with
> small memory and a large number of concurrent IOs. So appropriately
> reducing this value can improve performance.
> 
> Decreasing this value will reduce the compression ratio (except
> when input_size <LZ4_DISTANCE_MAX). But considering that erofs
> currently only supports 4k output, reducing this value will not
> significantly reduce the compression benefits.
> 
> The maximum value of LZ4_DISTANCE_MAX defined by lz4 is 64k, and
> we can only reduce this value. For the old kernel, it just can't
> reduce the memory allocation during rolling decompression without
> affecting the decompression result.
> 
> Signed-off-by: Huang Jianan <huangjianan@oppo.com>
> Signed-off-by: Guo Weichao <guoweichao@oppo.com>
> ---
> 
> change since v2:
> - use z_erofs_load_lz4_config to calculate lz4_distance_pages
> - add description about the compatibility of the old kernel version
> - drop useless comment
> 
>  fs/erofs/decompressor.c | 22 ++++++++++++++++++----
>  fs/erofs/erofs_fs.h     |  3 ++-
>  fs/erofs/internal.h     |  7 +++++++
>  fs/erofs/super.c        |  2 ++
>  4 files changed, 29 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
> index 1cb1ffd10569..0bb7903e3f9b 100644
> --- a/fs/erofs/decompressor.c
> +++ b/fs/erofs/decompressor.c
> @@ -28,6 +28,18 @@ struct z_erofs_decompressor {
>  	char *name;
>  };
>  
> +int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
> +			    struct erofs_super_block *dsb)
> +{
> +	u16 distance = le16_to_cpu(dsb->lz4_max_distance);
> +
> +	sbi->lz4_max_distance_pages = distance ?
> +					(DIV_ROUND_UP(distance, PAGE_SIZE) + 1) :

Unneeded parentheses here (I'll update it when applying).
Otherwise it looks good to me.

Reviewed-by: Gao Xiang <hsiangkao@redhat.com>

Thanks,
Gao Xiang


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] erofs: support adjust lz4 history window size
@ 2021-02-23  7:44   ` Gao Xiang
  0 siblings, 0 replies; 6+ messages in thread
From: Gao Xiang @ 2021-02-23  7:44 UTC (permalink / raw)
  To: Huang Jianan; +Cc: zhangshiming, guoweichao, linux-erofs, linux-kernel

On Tue, Feb 23, 2021 at 03:31:19PM +0800, Huang Jianan via Linux-erofs wrote:
> lz4 uses LZ4_DISTANCE_MAX to record history preservation. When
> using rolling decompression, a block with a higher compression
> ratio will cause a larger memory allocation (up to 64k). It may
> cause a large resource burden in extreme cases on devices with
> small memory and a large number of concurrent IOs. So appropriately
> reducing this value can improve performance.
> 
> Decreasing this value will reduce the compression ratio (except
> when input_size <LZ4_DISTANCE_MAX). But considering that erofs
> currently only supports 4k output, reducing this value will not
> significantly reduce the compression benefits.
> 
> The maximum value of LZ4_DISTANCE_MAX defined by lz4 is 64k, and
> we can only reduce this value. For the old kernel, it just can't
> reduce the memory allocation during rolling decompression without
> affecting the decompression result.
> 
> Signed-off-by: Huang Jianan <huangjianan@oppo.com>
> Signed-off-by: Guo Weichao <guoweichao@oppo.com>
> ---
> 
> change since v2:
> - use z_erofs_load_lz4_config to calculate lz4_distance_pages
> - add description about the compatibility of the old kernel version
> - drop useless comment
> 
>  fs/erofs/decompressor.c | 22 ++++++++++++++++++----
>  fs/erofs/erofs_fs.h     |  3 ++-
>  fs/erofs/internal.h     |  7 +++++++
>  fs/erofs/super.c        |  2 ++
>  4 files changed, 29 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
> index 1cb1ffd10569..0bb7903e3f9b 100644
> --- a/fs/erofs/decompressor.c
> +++ b/fs/erofs/decompressor.c
> @@ -28,6 +28,18 @@ struct z_erofs_decompressor {
>  	char *name;
>  };
>  
> +int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
> +			    struct erofs_super_block *dsb)
> +{
> +	u16 distance = le16_to_cpu(dsb->lz4_max_distance);
> +
> +	sbi->lz4_max_distance_pages = distance ?
> +					(DIV_ROUND_UP(distance, PAGE_SIZE) + 1) :

Unneeded parentheses here (I'll update it when applying).
Otherwise it looks good to me.

Reviewed-by: Gao Xiang <hsiangkao@redhat.com>

Thanks,
Gao Xiang


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] erofs: support adjust lz4 history window size
  2021-02-23  7:44   ` Gao Xiang
@ 2021-02-23  8:13     ` Gao Xiang via Linux-erofs
  -1 siblings, 0 replies; 6+ messages in thread
From: Gao Xiang @ 2021-02-23  8:13 UTC (permalink / raw)
  To: Huang Jianan; +Cc: zhangshiming, guoweichao, linux-erofs, linux-kernel

On Tue, Feb 23, 2021 at 03:44:18PM +0800, Gao Xiang wrote:
> On Tue, Feb 23, 2021 at 03:31:19PM +0800, Huang Jianan via Linux-erofs wrote:
> > lz4 uses LZ4_DISTANCE_MAX to record history preservation. When
> > using rolling decompression, a block with a higher compression
> > ratio will cause a larger memory allocation (up to 64k). It may
> > cause a large resource burden in extreme cases on devices with
> > small memory and a large number of concurrent IOs. So appropriately
> > reducing this value can improve performance.
> > 
> > Decreasing this value will reduce the compression ratio (except
> > when input_size <LZ4_DISTANCE_MAX). But considering that erofs
> > currently only supports 4k output, reducing this value will not
> > significantly reduce the compression benefits.
> > 
> > The maximum value of LZ4_DISTANCE_MAX defined by lz4 is 64k, and
> > we can only reduce this value. For the old kernel, it just can't
> > reduce the memory allocation during rolling decompression without
> > affecting the decompression result.
> > 
> > Signed-off-by: Huang Jianan <huangjianan@oppo.com>
> > Signed-off-by: Guo Weichao <guoweichao@oppo.com>
> > ---
> > 
> > change since v2:
> > - use z_erofs_load_lz4_config to calculate lz4_distance_pages
> > - add description about the compatibility of the old kernel version
> > - drop useless comment
> > 
> >  fs/erofs/decompressor.c | 22 ++++++++++++++++++----
> >  fs/erofs/erofs_fs.h     |  3 ++-
> >  fs/erofs/internal.h     |  7 +++++++
> >  fs/erofs/super.c        |  2 ++
> >  4 files changed, 29 insertions(+), 5 deletions(-)
> > 
> > diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
> > index 1cb1ffd10569..0bb7903e3f9b 100644
> > --- a/fs/erofs/decompressor.c
> > +++ b/fs/erofs/decompressor.c
> > @@ -28,6 +28,18 @@ struct z_erofs_decompressor {
> >  	char *name;
> >  };
> >  
> > +int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
> > +			    struct erofs_super_block *dsb)
> > +{
> > +	u16 distance = le16_to_cpu(dsb->lz4_max_distance);
> > +
> > +	sbi->lz4_max_distance_pages = distance ?
> > +					(DIV_ROUND_UP(distance, PAGE_SIZE) + 1) :
> 
> Unneeded parentheses here (I'll update it when applying).
> Otherwise it looks good to me.
> 
> Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
> 
> Thanks,
> Gao Xiang

Applied to dev-test temporarily with the following diff
(fix 80 char limitation, etc):

diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
index 0bb7903e3f9b..49347e681a53 100644
--- a/fs/erofs/decompressor.c
+++ b/fs/erofs/decompressor.c
@@ -34,9 +34,8 @@ int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
 	u16 distance = le16_to_cpu(dsb->lz4_max_distance);
 
 	sbi->lz4_max_distance_pages = distance ?
-					(DIV_ROUND_UP(distance, PAGE_SIZE) + 1) :
+					DIV_ROUND_UP(distance, PAGE_SIZE) + 1 :
 					LZ4_MAX_DISTANCE_PAGES;
-
 	return 0;
 }
 
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 4cb2395db45c..77965490dced 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -433,7 +433,7 @@ static inline void erofs_exit_shrinker(void) {}
 static inline int z_erofs_init_zip_subsystem(void) { return 0; }
 static inline void z_erofs_exit_zip_subsystem(void) {}
 static inline int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
-					  struct erofs_super_block *dsb) { return 0; }
+				struct erofs_super_block *dsb) { return 0; }
 #endif	/* !CONFIG_EROFS_FS_ZIP */
 
 #define EFSCORRUPTED    EUCLEAN         /* Filesystem is corrupted */
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index 11bc51e488dd..025c25d6e0f3 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -166,8 +166,6 @@ static int erofs_read_superblock(struct super_block *sb)
 	if (!check_layout_compatibility(sb, dsb))
 		goto out;
 
-	z_erofs_load_lz4_config(sbi, dsb);
-
 	sbi->blocks = le32_to_cpu(dsb->blocks);
 	sbi->meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
 #ifdef CONFIG_EROFS_FS_XATTR
@@ -189,6 +187,9 @@ static int erofs_read_superblock(struct super_block *sb)
 		ret = -EFSCORRUPTED;
 		goto out;
 	}
+
+	/* parse on-disk compression configurations */
+	z_erofs_load_lz4_config(sbi, dsb);
 	ret = 0;
 out:
 	kunmap(page);


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] erofs: support adjust lz4 history window size
@ 2021-02-23  8:13     ` Gao Xiang via Linux-erofs
  0 siblings, 0 replies; 6+ messages in thread
From: Gao Xiang via Linux-erofs @ 2021-02-23  8:13 UTC (permalink / raw)
  To: Huang Jianan; +Cc: zhangshiming, linux-erofs, guoweichao, linux-kernel

On Tue, Feb 23, 2021 at 03:44:18PM +0800, Gao Xiang wrote:
> On Tue, Feb 23, 2021 at 03:31:19PM +0800, Huang Jianan via Linux-erofs wrote:
> > lz4 uses LZ4_DISTANCE_MAX to record history preservation. When
> > using rolling decompression, a block with a higher compression
> > ratio will cause a larger memory allocation (up to 64k). It may
> > cause a large resource burden in extreme cases on devices with
> > small memory and a large number of concurrent IOs. So appropriately
> > reducing this value can improve performance.
> > 
> > Decreasing this value will reduce the compression ratio (except
> > when input_size <LZ4_DISTANCE_MAX). But considering that erofs
> > currently only supports 4k output, reducing this value will not
> > significantly reduce the compression benefits.
> > 
> > The maximum value of LZ4_DISTANCE_MAX defined by lz4 is 64k, and
> > we can only reduce this value. For the old kernel, it just can't
> > reduce the memory allocation during rolling decompression without
> > affecting the decompression result.
> > 
> > Signed-off-by: Huang Jianan <huangjianan@oppo.com>
> > Signed-off-by: Guo Weichao <guoweichao@oppo.com>
> > ---
> > 
> > change since v2:
> > - use z_erofs_load_lz4_config to calculate lz4_distance_pages
> > - add description about the compatibility of the old kernel version
> > - drop useless comment
> > 
> >  fs/erofs/decompressor.c | 22 ++++++++++++++++++----
> >  fs/erofs/erofs_fs.h     |  3 ++-
> >  fs/erofs/internal.h     |  7 +++++++
> >  fs/erofs/super.c        |  2 ++
> >  4 files changed, 29 insertions(+), 5 deletions(-)
> > 
> > diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
> > index 1cb1ffd10569..0bb7903e3f9b 100644
> > --- a/fs/erofs/decompressor.c
> > +++ b/fs/erofs/decompressor.c
> > @@ -28,6 +28,18 @@ struct z_erofs_decompressor {
> >  	char *name;
> >  };
> >  
> > +int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
> > +			    struct erofs_super_block *dsb)
> > +{
> > +	u16 distance = le16_to_cpu(dsb->lz4_max_distance);
> > +
> > +	sbi->lz4_max_distance_pages = distance ?
> > +					(DIV_ROUND_UP(distance, PAGE_SIZE) + 1) :
> 
> Unneeded parentheses here (I'll update it when applying).
> Otherwise it looks good to me.
> 
> Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
> 
> Thanks,
> Gao Xiang

Applied to dev-test temporarily with the following diff
(fix 80 char limitation, etc):

diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
index 0bb7903e3f9b..49347e681a53 100644
--- a/fs/erofs/decompressor.c
+++ b/fs/erofs/decompressor.c
@@ -34,9 +34,8 @@ int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
 	u16 distance = le16_to_cpu(dsb->lz4_max_distance);
 
 	sbi->lz4_max_distance_pages = distance ?
-					(DIV_ROUND_UP(distance, PAGE_SIZE) + 1) :
+					DIV_ROUND_UP(distance, PAGE_SIZE) + 1 :
 					LZ4_MAX_DISTANCE_PAGES;
-
 	return 0;
 }
 
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 4cb2395db45c..77965490dced 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -433,7 +433,7 @@ static inline void erofs_exit_shrinker(void) {}
 static inline int z_erofs_init_zip_subsystem(void) { return 0; }
 static inline void z_erofs_exit_zip_subsystem(void) {}
 static inline int z_erofs_load_lz4_config(struct erofs_sb_info *sbi,
-					  struct erofs_super_block *dsb) { return 0; }
+				struct erofs_super_block *dsb) { return 0; }
 #endif	/* !CONFIG_EROFS_FS_ZIP */
 
 #define EFSCORRUPTED    EUCLEAN         /* Filesystem is corrupted */
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index 11bc51e488dd..025c25d6e0f3 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -166,8 +166,6 @@ static int erofs_read_superblock(struct super_block *sb)
 	if (!check_layout_compatibility(sb, dsb))
 		goto out;
 
-	z_erofs_load_lz4_config(sbi, dsb);
-
 	sbi->blocks = le32_to_cpu(dsb->blocks);
 	sbi->meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
 #ifdef CONFIG_EROFS_FS_XATTR
@@ -189,6 +187,9 @@ static int erofs_read_superblock(struct super_block *sb)
 		ret = -EFSCORRUPTED;
 		goto out;
 	}
+
+	/* parse on-disk compression configurations */
+	z_erofs_load_lz4_config(sbi, dsb);
 	ret = 0;
 out:
 	kunmap(page);


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-02-23  8:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-23  7:31 [PATCH v3] erofs: support adjust lz4 history window size Huang Jianan
2021-02-23  7:31 ` Huang Jianan via Linux-erofs
2021-02-23  7:44 ` Gao Xiang
2021-02-23  7:44   ` Gao Xiang
2021-02-23  8:13   ` Gao Xiang
2021-02-23  8:13     ` Gao Xiang via Linux-erofs

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.