* [PATCH 0/2] erofs: support deflate decompress by using Intel QAT
@ 2025-04-10 4:20 Bo Liu
2025-04-10 4:20 ` [PATCH 1/2] erofs: remove duplicate code Bo Liu
2025-04-10 4:20 ` [PATCH 2/2] erofs: support deflate decompress by using Intel QAT Bo Liu
0 siblings, 2 replies; 7+ messages in thread
From: Bo Liu @ 2025-04-10 4:20 UTC (permalink / raw)
To: xiang, chao; +Cc: linux-erofs, linux-kernel, Bo Liu
This patch introdueces the use of the Intel QAT to decompress compressed
data in the EROFS filesystem, aiming to improve the decompression speed
of compressed datea.
We created a 285MiB compressed file and then used the following command to
create EROFS images with different cluster size.
# mkfs.erofs -zdeflate,level=9 -C16384
fio command was used to test random read and small random read(~5%) and
sequential read performance.
# fio -filename=testfile -bs=4k -rw=read -name=job1
# fio -filename=testfile -bs=4k -rw=randread -name=job1
# fio -filename=testfile -bs=4k -rw=randread --io_size=14m -name=job1
Here are some performance numbers for reference:
Processors: Intel(R) Xeon(R) 6766E(144 core)
Memory: 521 GiB
|-----------------------------------------------------------------------------|
| | Cluster size | sequential read | randread | small randread(5%) |
|-----------|--------------|-----------------|-----------|--------------------|
| Intel QAT | 4096 | 538 MiB/s | 112 MiB/s | 20.76 MiB/s |
| Intel QAT | 16384 | 699 MiB/s | 158 MiB/s | 21.02 MiB/s |
| Intel QAT | 65536 | 917 MiB/s | 278 MiB/s | 20.90 MiB/s |
| Intel QAT | 131072 | 1056 MiB/s | 351 MiB/s | 23.36 MiB/s |
| Intel QAT | 262144 | 1145 MiB/s | 431 MiB/s | 26.66 MiB/s |
| deflate | 4096 | 499 MiB/s | 108 MiB/s | 21.50 MiB/s |
| deflate | 16384 | 422 MiB/s | 125 MiB/s | 18.94 MiB/s |
| deflate | 65536 | 452 MiB/s | 159 MiB/s | 13.02 MiB/s |
| deflate | 65536 | 452 MiB/s | 177 MiB/s | 11.44 MiB/s |
| deflate | 262144 | 466 MiB/s | 194 MiB/s | 10.60 MiB/s |
Bo Liu (2):
erofs: remove duplicate code
erofs: support deflate decompress by using Intel QAT
fs/erofs/decompressor_deflate.c | 145 +++++++++++++++++++++++++++++++-
fs/erofs/internal.h | 1 +
fs/erofs/sysfs.c | 30 +++++++
fs/erofs/zdata.c | 1 -
4 files changed, 175 insertions(+), 2 deletions(-)
--
2.31.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 1/2] erofs: remove duplicate code 2025-04-10 4:20 [PATCH 0/2] erofs: support deflate decompress by using Intel QAT Bo Liu @ 2025-04-10 4:20 ` Bo Liu 2025-04-10 5:34 ` Gao Xiang 2025-04-10 4:20 ` [PATCH 2/2] erofs: support deflate decompress by using Intel QAT Bo Liu 1 sibling, 1 reply; 7+ messages in thread From: Bo Liu @ 2025-04-10 4:20 UTC (permalink / raw) To: xiang, chao; +Cc: linux-erofs, linux-kernel, Bo Liu Remove duplicate code in function z_erofs_register_pcluster() Signed-off-by: Bo Liu <liubo03@inspur.com> --- fs/erofs/zdata.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index 0671184d9cf1..5c061aaeeb45 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -725,7 +725,6 @@ static int z_erofs_register_pcluster(struct z_erofs_frontend *fe) lockref_init(&pcl->lockref); /* one ref for this request */ pcl->algorithmformat = map->m_algorithmformat; pcl->pclustersize = map->m_plen; - pcl->pageofs_in = pageofs_in; pcl->length = 0; pcl->partial = true; pcl->next = fe->head; -- 2.31.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] erofs: remove duplicate code 2025-04-10 4:20 ` [PATCH 1/2] erofs: remove duplicate code Bo Liu @ 2025-04-10 5:34 ` Gao Xiang 0 siblings, 0 replies; 7+ messages in thread From: Gao Xiang @ 2025-04-10 5:34 UTC (permalink / raw) To: Bo Liu, xiang, chao; +Cc: linux-erofs, linux-kernel On 2025/4/10 12:20, Bo Liu wrote: > Remove duplicate code in function z_erofs_register_pcluster() > > Signed-off-by: Bo Liu <liubo03@inspur.com> Thanks for catching this, will apply it first: Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com> Thanks, Gao Xiang ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] erofs: support deflate decompress by using Intel QAT 2025-04-10 4:20 [PATCH 0/2] erofs: support deflate decompress by using Intel QAT Bo Liu 2025-04-10 4:20 ` [PATCH 1/2] erofs: remove duplicate code Bo Liu @ 2025-04-10 4:20 ` Bo Liu 2025-04-11 6:30 ` kernel test robot ` (2 more replies) 1 sibling, 3 replies; 7+ messages in thread From: Bo Liu @ 2025-04-10 4:20 UTC (permalink / raw) To: xiang, chao; +Cc: linux-erofs, linux-kernel, Bo Liu This patch introdueces the use of the Intel QAT to decompress compressed data in the EROFS filesystem, aiming to improve the decompression speed of compressed datea. We created a 285MiB compressed file and then used the following command to create EROFS images with different cluster size. # mkfs.erofs -zdeflate,level=9 -C16384 fio command was used to test random read and small random read(~5%) and sequential read performance. # fio -filename=testfile -bs=4k -rw=read -name=job1 # fio -filename=testfile -bs=4k -rw=randread -name=job1 # fio -filename=testfile -bs=4k -rw=randread --io_size=14m -name=job1 Here are some performance numbers for reference: Processors: Intel(R) Xeon(R) 6766E(144 core) Memory: 521 GiB |-----------------------------------------------------------------------------| | | Cluster size | sequential read | randread | small randread(5%) | |-----------|--------------|-----------------|-----------|--------------------| | Intel QAT | 4096 | 538 MiB/s | 112 MiB/s | 20.76 MiB/s | | Intel QAT | 16384 | 699 MiB/s | 158 MiB/s | 21.02 MiB/s | | Intel QAT | 65536 | 917 MiB/s | 278 MiB/s | 20.90 MiB/s | | Intel QAT | 131072 | 1056 MiB/s | 351 MiB/s | 23.36 MiB/s | | Intel QAT | 262144 | 1145 MiB/s | 431 MiB/s | 26.66 MiB/s | | deflate | 4096 | 499 MiB/s | 108 MiB/s | 21.50 MiB/s | | deflate | 16384 | 422 MiB/s | 125 MiB/s | 18.94 MiB/s | | deflate | 65536 | 452 MiB/s | 159 MiB/s | 13.02 MiB/s | | deflate | 65536 | 452 MiB/s | 177 MiB/s | 11.44 MiB/s | | deflate | 262144 | 466 MiB/s | 194 MiB/s | 10.60 MiB/s | Signed-off-by: Bo Liu <liubo03@inspur.com> --- fs/erofs/decompressor_deflate.c | 145 +++++++++++++++++++++++++++++++- fs/erofs/internal.h | 1 + fs/erofs/sysfs.c | 30 +++++++ 3 files changed, 175 insertions(+), 1 deletion(-) diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c index c6908a487054..a293c44e86d2 100644 --- a/fs/erofs/decompressor_deflate.c +++ b/fs/erofs/decompressor_deflate.c @@ -1,5 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include <linux/zlib.h> +#include <linux/scatterlist.h> +#include <crypto/acompress.h> + #include "compress.h" struct z_erofs_deflate { @@ -97,7 +100,7 @@ static int z_erofs_load_deflate_config(struct super_block *sb, return -ENOMEM; } -static int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq, +static int __z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq, struct page **pgpl) { struct super_block *sb = rq->sb; @@ -178,6 +181,146 @@ static int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq, return err; } +static int z_erofs_crypto_decompress_mem(struct z_erofs_decompress_req *rq) +{ + struct erofs_sb_info *sbi = EROFS_SB(rq->sb); + unsigned int nrpages_out = + PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; + unsigned int nrpages_in = PAGE_ALIGN(rq->inputsize) >> PAGE_SHIFT; + struct sg_table st_src, st_dst; + struct scatterlist *sg_src, *sg_dst; + struct acomp_req *req; + struct crypto_wait wait; + u8 *headpage; + int ret, i; + + WARN_ON(!*rq->in); + headpage = kmap_local_page(*rq->in); + + ret = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in, + min_t(unsigned int, rq->inputsize, + rq->sb->s_blocksize - rq->pageofs_in)); + + kunmap_local(headpage); + if (ret) { + return ret; + } + + req = acomp_request_alloc(sbi->erofs_tfm); + if (!req) { + erofs_err(rq->sb, "failed to alloc decompress request"); + return -ENOMEM; + } + + if (sg_alloc_table(&st_src, nrpages_in, GFP_KERNEL)) { + acomp_request_free(req); + return -ENOMEM; + } + + if (sg_alloc_table(&st_dst, nrpages_out, GFP_KERNEL)) { + acomp_request_free(req); + sg_free_table(&st_src); + return -ENOMEM; + } + + for_each_sg(st_src.sgl, sg_src, nrpages_in, i) { + if (i == 0) + sg_set_page(sg_src, rq->in[0], + PAGE_SIZE - rq->pageofs_in, rq->pageofs_in); + else + sg_set_page(sg_src, rq->in[i], PAGE_SIZE, 0); + } + + i = 0; + for_each_sg(st_dst.sgl, sg_dst, nrpages_out, i) { + if (i == 0) + sg_set_page(sg_dst, rq->out[0], + PAGE_SIZE - rq->pageofs_out, rq->pageofs_out); + else + sg_set_page(sg_dst, rq->out[i], PAGE_SIZE, 0); + } + + acomp_request_set_params(req, st_src.sgl, + st_dst.sgl, rq->inputsize, rq->outputsize); + + crypto_init_wait(&wait); + acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + crypto_req_done, &wait); + + ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); + if (ret < 0) { + if (ret == -EBADMSG && rq->partial_decoding) { + ret = 0; + } else { + erofs_err(rq->sb, "failed to decompress %d in[%u, %u] out[%u]", + ret, rq->inputsize, rq->pageofs_in, rq->outputsize); + ret = -EIO; + } + } else { + ret = 0; + } + + acomp_request_free(req); + sg_free_table(&st_src); + sg_free_table(&st_dst); + return ret; +} + +static int z_erofs_crypto_prepare_dstpages(struct z_erofs_decompress_req *rq, + struct page **pagepool) +{ + const unsigned int nr = + PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; + unsigned int i; + + for (i = 0; i < nr; ++i) { + struct page *const page = rq->out[i]; + struct page *victim; + + if (!page) { + victim = __erofs_allocpage(pagepool, rq->gfp, true); + if (!victim) + return -ENOMEM; + set_page_private(victim, Z_EROFS_SHORTLIVED_PAGE); + rq->out[i] = victim; + } + } + return 0; +} + +static int __z_erofs_deflate_crypto_decompress(struct z_erofs_decompress_req *rq, + struct page **pgpl) +{ + const unsigned int nrpages_out = + PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; + int ret; + + /* one optimized fast path only for non bigpcluster cases yet */ + if (rq->inputsize <= PAGE_SIZE && nrpages_out == 1 && !rq->inplace_io) { + WARN_ON(!*rq->out); + goto dstmap_out; + } + + ret = z_erofs_crypto_prepare_dstpages(rq, pgpl); + if (ret < 0) + return ret; + +dstmap_out: + return z_erofs_crypto_decompress_mem(rq); +} + +static int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq, + struct page **pgpl) +{ + struct super_block *sb = rq->sb; + struct erofs_sb_info *sbi = EROFS_SB(sb); + + if (sbi->erofs_tfm) + return __z_erofs_deflate_crypto_decompress(rq, pgpl); + else + return __z_erofs_deflate_decompress(rq, pgpl); +} + const struct z_erofs_decompressor z_erofs_deflate_decomp = { .config = z_erofs_load_deflate_config, .decompress = z_erofs_deflate_decompress, diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 4ac188d5d894..96fcee07d353 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -122,6 +122,7 @@ struct erofs_sb_info { /* pseudo inode to manage cached pages */ struct inode *managed_cache; + struct crypto_acomp *erofs_tfm; struct erofs_sb_lz4_info lz4; #endif /* CONFIG_EROFS_FS_ZIP */ struct inode *packed_inode; diff --git a/fs/erofs/sysfs.c b/fs/erofs/sysfs.c index dad4e6c6c155..d4630697dafd 100644 --- a/fs/erofs/sysfs.c +++ b/fs/erofs/sysfs.c @@ -5,6 +5,7 @@ */ #include <linux/sysfs.h> #include <linux/kobject.h> +#include <crypto/acompress.h> #include "internal.h" @@ -13,6 +14,7 @@ enum { attr_drop_caches, attr_pointer_ui, attr_pointer_bool, + attr_comp_crypto, }; enum { @@ -59,12 +61,14 @@ static struct erofs_attr erofs_attr_##_name = { \ #ifdef CONFIG_EROFS_FS_ZIP EROFS_ATTR_RW_UI(sync_decompress, erofs_mount_opts); EROFS_ATTR_FUNC(drop_caches, 0200); +EROFS_ATTR_FUNC(comp_crypto, 0644); #endif static struct attribute *erofs_attrs[] = { #ifdef CONFIG_EROFS_FS_ZIP ATTR_LIST(sync_decompress), ATTR_LIST(drop_caches), + ATTR_LIST(comp_crypto), #endif NULL, }; @@ -128,6 +132,12 @@ static ssize_t erofs_attr_show(struct kobject *kobj, if (!ptr) return 0; return sysfs_emit(buf, "%d\n", *(bool *)ptr); + case attr_comp_crypto: + if (sbi->erofs_tfm) + return sysfs_emit(buf, "%s\n", + crypto_comp_alg_common(sbi->erofs_tfm)->base.cra_driver_name); + else + return sysfs_emit(buf, "NONE\n"); } return 0; } @@ -181,6 +191,26 @@ static ssize_t erofs_attr_store(struct kobject *kobj, struct attribute *attr, if (t & 1) invalidate_mapping_pages(MNGD_MAPPING(sbi), 0, -1); return len; + case attr_comp_crypto: + buf = skip_spaces(buf); + if (!strncmp(buf, "none", 4)) { + if (sbi->erofs_tfm) + crypto_free_acomp(sbi->erofs_tfm); + sbi->erofs_tfm = NULL; + return len; + } + + if (!strncmp(buf, "qat_deflate", 11)) { + if (sbi->erofs_tfm) + crypto_free_acomp(sbi->erofs_tfm); + sbi->erofs_tfm = crypto_alloc_acomp("qat_deflate", 0, 0); + if (IS_ERR(sbi->erofs_tfm)) { + sbi->erofs_tfm = NULL; + return -ENODEV; + } + return len; + } + return -EINVAL; #endif } return 0; -- 2.31.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] erofs: support deflate decompress by using Intel QAT 2025-04-10 4:20 ` [PATCH 2/2] erofs: support deflate decompress by using Intel QAT Bo Liu @ 2025-04-11 6:30 ` kernel test robot 2025-04-11 7:44 ` kernel test robot 2025-05-13 5:47 ` Gao Xiang 2 siblings, 0 replies; 7+ messages in thread From: kernel test robot @ 2025-04-11 6:30 UTC (permalink / raw) To: Bo Liu, xiang, chao; +Cc: oe-kbuild-all, linux-erofs, linux-kernel, Bo Liu Hi Bo, kernel test robot noticed the following build errors: [auto build test ERROR on xiang-erofs/dev-test] [also build test ERROR on xiang-erofs/dev linus/master v6.15-rc1 next-20250410] [cannot apply to xiang-erofs/fixes] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Bo-Liu/erofs-remove-duplicate-code/20250410-122442 base: https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git dev-test patch link: https://lore.kernel.org/r/20250410042048.3044-3-liubo03%40inspur.com patch subject: [PATCH 2/2] erofs: support deflate decompress by using Intel QAT config: arc-randconfig-001-20250411 (https://download.01.org/0day-ci/archive/20250411/202504111440.2DIupC2G-lkp@intel.com/config) compiler: arc-linux-gcc (GCC) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250411/202504111440.2DIupC2G-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202504111440.2DIupC2G-lkp@intel.com/ All errors (new ones prefixed by >>): fs/erofs/sysfs.c: In function 'erofs_attr_show': >> fs/erofs/sysfs.c:136:24: error: 'struct erofs_sb_info' has no member named 'erofs_tfm' 136 | if (sbi->erofs_tfm) | ^~ fs/erofs/sysfs.c:138:59: error: 'struct erofs_sb_info' has no member named 'erofs_tfm' 138 | crypto_comp_alg_common(sbi->erofs_tfm)->base.cra_driver_name); | ^~ vim +136 fs/erofs/sysfs.c 115 116 static ssize_t erofs_attr_show(struct kobject *kobj, 117 struct attribute *attr, char *buf) 118 { 119 struct erofs_sb_info *sbi = container_of(kobj, struct erofs_sb_info, 120 s_kobj); 121 struct erofs_attr *a = container_of(attr, struct erofs_attr, attr); 122 unsigned char *ptr = __struct_ptr(sbi, a->struct_type, a->offset); 123 124 switch (a->attr_id) { 125 case attr_feature: 126 return sysfs_emit(buf, "supported\n"); 127 case attr_pointer_ui: 128 if (!ptr) 129 return 0; 130 return sysfs_emit(buf, "%u\n", *(unsigned int *)ptr); 131 case attr_pointer_bool: 132 if (!ptr) 133 return 0; 134 return sysfs_emit(buf, "%d\n", *(bool *)ptr); 135 case attr_comp_crypto: > 136 if (sbi->erofs_tfm) 137 return sysfs_emit(buf, "%s\n", 138 crypto_comp_alg_common(sbi->erofs_tfm)->base.cra_driver_name); 139 else 140 return sysfs_emit(buf, "NONE\n"); 141 } 142 return 0; 143 } 144 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] erofs: support deflate decompress by using Intel QAT 2025-04-10 4:20 ` [PATCH 2/2] erofs: support deflate decompress by using Intel QAT Bo Liu 2025-04-11 6:30 ` kernel test robot @ 2025-04-11 7:44 ` kernel test robot 2025-05-13 5:47 ` Gao Xiang 2 siblings, 0 replies; 7+ messages in thread From: kernel test robot @ 2025-04-11 7:44 UTC (permalink / raw) To: Bo Liu, xiang, chao Cc: llvm, oe-kbuild-all, linux-erofs, linux-kernel, Bo Liu Hi Bo, kernel test robot noticed the following build errors: [auto build test ERROR on xiang-erofs/dev-test] [also build test ERROR on xiang-erofs/dev linus/master v6.15-rc1] [cannot apply to xiang-erofs/fixes next-20250411] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Bo-Liu/erofs-remove-duplicate-code/20250410-122442 base: https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git dev-test patch link: https://lore.kernel.org/r/20250410042048.3044-3-liubo03%40inspur.com patch subject: [PATCH 2/2] erofs: support deflate decompress by using Intel QAT config: x86_64-buildonly-randconfig-003-20250411 (https://download.01.org/0day-ci/archive/20250411/202504111545.9ZYfP6Gr-lkp@intel.com/config) compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250411/202504111545.9ZYfP6Gr-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202504111545.9ZYfP6Gr-lkp@intel.com/ All errors (new ones prefixed by >>): >> fs/erofs/sysfs.c:136:12: error: no member named 'erofs_tfm' in 'struct erofs_sb_info' 136 | if (sbi->erofs_tfm) | ~~~ ^ fs/erofs/sysfs.c:138:33: error: no member named 'erofs_tfm' in 'struct erofs_sb_info' 138 | crypto_comp_alg_common(sbi->erofs_tfm)->base.cra_driver_name); | ~~~ ^ 2 errors generated. vim +136 fs/erofs/sysfs.c 115 116 static ssize_t erofs_attr_show(struct kobject *kobj, 117 struct attribute *attr, char *buf) 118 { 119 struct erofs_sb_info *sbi = container_of(kobj, struct erofs_sb_info, 120 s_kobj); 121 struct erofs_attr *a = container_of(attr, struct erofs_attr, attr); 122 unsigned char *ptr = __struct_ptr(sbi, a->struct_type, a->offset); 123 124 switch (a->attr_id) { 125 case attr_feature: 126 return sysfs_emit(buf, "supported\n"); 127 case attr_pointer_ui: 128 if (!ptr) 129 return 0; 130 return sysfs_emit(buf, "%u\n", *(unsigned int *)ptr); 131 case attr_pointer_bool: 132 if (!ptr) 133 return 0; 134 return sysfs_emit(buf, "%d\n", *(bool *)ptr); 135 case attr_comp_crypto: > 136 if (sbi->erofs_tfm) 137 return sysfs_emit(buf, "%s\n", 138 crypto_comp_alg_common(sbi->erofs_tfm)->base.cra_driver_name); 139 else 140 return sysfs_emit(buf, "NONE\n"); 141 } 142 return 0; 143 } 144 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] erofs: support deflate decompress by using Intel QAT 2025-04-10 4:20 ` [PATCH 2/2] erofs: support deflate decompress by using Intel QAT Bo Liu 2025-04-11 6:30 ` kernel test robot 2025-04-11 7:44 ` kernel test robot @ 2025-05-13 5:47 ` Gao Xiang 2 siblings, 0 replies; 7+ messages in thread From: Gao Xiang @ 2025-05-13 5:47 UTC (permalink / raw) To: Bo Liu, xiang, chao; +Cc: linux-erofs, linux-kernel Hi Bo, On 2025/4/10 12:20, Bo Liu wrote: > This patch introdueces the use of the Intel QAT to decompress compressed > data in the EROFS filesystem, aiming to improve the decompression speed > of compressed datea. > > We created a 285MiB compressed file and then used the following command to > create EROFS images with different cluster size. > # mkfs.erofs -zdeflate,level=9 -C16384 > > fio command was used to test random read and small random read(~5%) and > sequential read performance. > # fio -filename=testfile -bs=4k -rw=read -name=job1 > # fio -filename=testfile -bs=4k -rw=randread -name=job1 > # fio -filename=testfile -bs=4k -rw=randread --io_size=14m -name=job1 > > Here are some performance numbers for reference: > > Processors: Intel(R) Xeon(R) 6766E(144 core) > Memory: 521 GiB > > |-----------------------------------------------------------------------------| > | | Cluster size | sequential read | randread | small randread(5%) | > |-----------|--------------|-----------------|-----------|--------------------| > | Intel QAT | 4096 | 538 MiB/s | 112 MiB/s | 20.76 MiB/s | > | Intel QAT | 16384 | 699 MiB/s | 158 MiB/s | 21.02 MiB/s | > | Intel QAT | 65536 | 917 MiB/s | 278 MiB/s | 20.90 MiB/s | > | Intel QAT | 131072 | 1056 MiB/s | 351 MiB/s | 23.36 MiB/s | > | Intel QAT | 262144 | 1145 MiB/s | 431 MiB/s | 26.66 MiB/s | > | deflate | 4096 | 499 MiB/s | 108 MiB/s | 21.50 MiB/s | > | deflate | 16384 | 422 MiB/s | 125 MiB/s | 18.94 MiB/s | > | deflate | 65536 | 452 MiB/s | 159 MiB/s | 13.02 MiB/s | > | deflate | 65536 | 452 MiB/s | 177 MiB/s | 11.44 MiB/s | > | deflate | 262144 | 466 MiB/s | 194 MiB/s | 10.60 MiB/s | > > Signed-off-by: Bo Liu <liubo03@inspur.com> Sorry for late reply due to internal stuffs. > --- > fs/erofs/decompressor_deflate.c | 145 +++++++++++++++++++++++++++++++- > fs/erofs/internal.h | 1 + > fs/erofs/sysfs.c | 30 +++++++ > 3 files changed, 175 insertions(+), 1 deletion(-) > > diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c > index c6908a487054..a293c44e86d2 100644 > --- a/fs/erofs/decompressor_deflate.c > +++ b/fs/erofs/decompressor_deflate.c > @@ -1,5 +1,8 @@ > // SPDX-License-Identifier: GPL-2.0-or-later > #include <linux/zlib.h> > +#include <linux/scatterlist.h> > +#include <crypto/acompress.h> I guess we could move this feature into a new file called "decompressor_crypto.c"? > + > #include "compress.h" > > struct z_erofs_deflate { > @@ -97,7 +100,7 @@ static int z_erofs_load_deflate_config(struct super_block *sb, > return -ENOMEM; > } > > -static int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq, > +static int __z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq, > struct page **pgpl) > { > struct super_block *sb = rq->sb; > @@ -178,6 +181,146 @@ static int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq, > return err; > } > > +static int z_erofs_crypto_decompress_mem(struct z_erofs_decompress_req *rq) > +{ > + struct erofs_sb_info *sbi = EROFS_SB(rq->sb); > + unsigned int nrpages_out = > + PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; > + unsigned int nrpages_in = PAGE_ALIGN(rq->inputsize) >> PAGE_SHIFT; I've optimized out those fields in commit 0243cc257ffa ("erofs: move {in,out}pages into struct z_erofs_decompress_req") so we don't need to recalculate here again. > + struct sg_table st_src, st_dst; > + struct scatterlist *sg_src, *sg_dst; > + struct acomp_req *req; > + struct crypto_wait wait; > + u8 *headpage; > + int ret, i; > + > + WARN_ON(!*rq->in); > + headpage = kmap_local_page(*rq->in); > + > + ret = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in, > + min_t(unsigned int, rq->inputsize, > + rq->sb->s_blocksize - rq->pageofs_in)); > + > + kunmap_local(headpage); > + if (ret) { > + return ret; > + } Unnecessary brace. > + > + req = acomp_request_alloc(sbi->erofs_tfm); > + if (!req) { > + erofs_err(rq->sb, "failed to alloc decompress request"); > + return -ENOMEM; > + } > + > + if (sg_alloc_table(&st_src, nrpages_in, GFP_KERNEL)) { > + acomp_request_free(req); > + return -ENOMEM; > + } > + > + if (sg_alloc_table(&st_dst, nrpages_out, GFP_KERNEL)) { > + acomp_request_free(req); > + sg_free_table(&st_src); > + return -ENOMEM; > + } > + > + for_each_sg(st_src.sgl, sg_src, nrpages_in, i) { > + if (i == 0) > + sg_set_page(sg_src, rq->in[0], > + PAGE_SIZE - rq->pageofs_in, rq->pageofs_in); > + else > + sg_set_page(sg_src, rq->in[i], PAGE_SIZE, 0); ^ should we consider rq->inputsize here? > + } > + > + i = 0; > + for_each_sg(st_dst.sgl, sg_dst, nrpages_out, i) { > + if (i == 0) > + sg_set_page(sg_dst, rq->out[0], > + PAGE_SIZE - rq->pageofs_out, rq->pageofs_out); > + else > + sg_set_page(sg_dst, rq->out[i], PAGE_SIZE, 0); ^ should we consider rq->outputsize here? > + } > + > + acomp_request_set_params(req, st_src.sgl, > + st_dst.sgl, rq->inputsize, rq->outputsize); > + > + crypto_init_wait(&wait); > + acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, > + crypto_req_done, &wait); > + > + ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); > + if (ret < 0) { > + if (ret == -EBADMSG && rq->partial_decoding) { Does QAT support partial decompression? > + ret = 0; > + } else { > + erofs_err(rq->sb, "failed to decompress %d in[%u, %u] out[%u]", > + ret, rq->inputsize, rq->pageofs_in, rq->outputsize); > + ret = -EIO; > + } > + } else { > + ret = 0; > + } > + > + acomp_request_free(req); > + sg_free_table(&st_src); > + sg_free_table(&st_dst); > + return ret; > +} > + > +static int z_erofs_crypto_prepare_dstpages(struct z_erofs_decompress_req *rq, > + struct page **pagepool) > +{ > + const unsigned int nr = > + PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; same here. Also I suggest fold this `z_erofs_crypto_prepare_dstpages()` into __z_erofs_deflate_crypto_decompress(). > + unsigned int i; > + > + for (i = 0; i < nr; ++i) { > + struct page *const page = rq->out[i]; > + struct page *victim; > + > + if (!page) { > + victim = __erofs_allocpage(pagepool, rq->gfp, true); > + if (!victim) > + return -ENOMEM; > + set_page_private(victim, Z_EROFS_SHORTLIVED_PAGE); > + rq->out[i] = victim; > + } > + } > + return 0; > +} > + > +static int __z_erofs_deflate_crypto_decompress(struct z_erofs_decompress_req *rq, > + struct page **pgpl) It seems this function can be used for other hardware accelerators, so I guess z_erofs_crypto_decompress is enough. > +{ > + const unsigned int nrpages_out = > + PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; > + int ret; > + > + /* one optimized fast path only for non bigpcluster cases yet */ > + if (rq->inputsize <= PAGE_SIZE && nrpages_out == 1 && !rq->inplace_io) { > + WARN_ON(!*rq->out); > + goto dstmap_out; > + } > + > + ret = z_erofs_crypto_prepare_dstpages(rq, pgpl); > + if (ret < 0) > + return ret; > + > +dstmap_out: > + return z_erofs_crypto_decompress_mem(rq); > +} > + > +static int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq, > + struct page **pgpl) I wonder if it's possible to add a hardware acceleralor list such as struct z_erofs_crypto_engine { char *name; struct z_erofs_decompressor *decomp; bool enabled; }; struct z_erofs_crypto_engine eng = { { "qat_deflate", &z_erofs_deflate_decomp }, ... }; so that we could add more hardware accelerators easily. > +{ > + struct super_block *sb = rq->sb; > + struct erofs_sb_info *sbi = EROFS_SB(sb); > + > + if (sbi->erofs_tfm) > + return __z_erofs_deflate_crypto_decompress(rq, pgpl); > + else > + return __z_erofs_deflate_decompress(rq, pgpl); > +} > + > const struct z_erofs_decompressor z_erofs_deflate_decomp = { > .config = z_erofs_load_deflate_config, > .decompress = z_erofs_deflate_decompress, > diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h> index 4ac188d5d894..96fcee07d353 100644 > --- a/fs/erofs/internal.h > +++ b/fs/erofs/internal.h > @@ -122,6 +122,7 @@ struct erofs_sb_info { > /* pseudo inode to manage cached pages */ > struct inode *managed_cache; > > + struct crypto_acomp *erofs_tfm; > struct erofs_sb_lz4_info lz4; > #endif /* CONFIG_EROFS_FS_ZIP */ > struct inode *packed_inode; > diff --git a/fs/erofs/sysfs.c b/fs/erofs/sysfs.c > index dad4e6c6c155..d4630697dafd 100644 > --- a/fs/erofs/sysfs.c > +++ b/fs/erofs/sysfs.c > @@ -5,6 +5,7 @@ > */ > #include <linux/sysfs.h> > #include <linux/kobject.h> > +#include <crypto/acompress.h> > > #include "internal.h" > > @@ -13,6 +14,7 @@ enum { > attr_drop_caches, > attr_pointer_ui, > attr_pointer_bool, > + attr_comp_crypto, > }; > > enum { > @@ -59,12 +61,14 @@ static struct erofs_attr erofs_attr_##_name = { \ > #ifdef CONFIG_EROFS_FS_ZIP > EROFS_ATTR_RW_UI(sync_decompress, erofs_mount_opts); > EROFS_ATTR_FUNC(drop_caches, 0200); > +EROFS_ATTR_FUNC(comp_crypto, 0644); > #endif > > static struct attribute *erofs_attrs[] = { > #ifdef CONFIG_EROFS_FS_ZIP > ATTR_LIST(sync_decompress), > ATTR_LIST(drop_caches), > + ATTR_LIST(comp_crypto), > #endif > NULL, > }; > @@ -128,6 +132,12 @@ static ssize_t erofs_attr_show(struct kobject *kobj, > if (!ptr) > return 0; > return sysfs_emit(buf, "%d\n", *(bool *)ptr); > + case attr_comp_crypto: > + if (sbi->erofs_tfm) > + return sysfs_emit(buf, "%s\n", > + crypto_comp_alg_common(sbi->erofs_tfm)->base.cra_driver_name); > + else > + return sysfs_emit(buf, "NONE\n"); > } > return 0; > } > @@ -181,6 +191,26 @@ static ssize_t erofs_attr_store(struct kobject *kobj, struct attribute *attr, > if (t & 1) > invalidate_mapping_pages(MNGD_MAPPING(sbi), 0, -1); > return len; > + case attr_comp_crypto: Then I'd like to make this sysfs to enable accelerators. Thanks, Gao XIang ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-05-13 5:47 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-04-10 4:20 [PATCH 0/2] erofs: support deflate decompress by using Intel QAT Bo Liu 2025-04-10 4:20 ` [PATCH 1/2] erofs: remove duplicate code Bo Liu 2025-04-10 5:34 ` Gao Xiang 2025-04-10 4:20 ` [PATCH 2/2] erofs: support deflate decompress by using Intel QAT Bo Liu 2025-04-11 6:30 ` kernel test robot 2025-04-11 7:44 ` kernel test robot 2025-05-13 5:47 ` Gao Xiang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox