From: Daeho Jeong <daehoje...@google.com> By profiling f2fs compression works, I've found vmap() callings are bottlenecks of f2fs decompression path. Changing these with vm_map_ram(), we can enhance f2fs decompression speed pretty much.
[Verification] dd if=/dev/zero of=dummy bs=1m count=1000 echo 3 > /proc/sys/vm/drop_caches dd if=dummy of=/dev/zero bs=512k - w/o compression - 1048576000 bytes (0.9 G) copied, 1.999384 s, 500 M/s 1048576000 bytes (0.9 G) copied, 2.035988 s, 491 M/s 1048576000 bytes (0.9 G) copied, 2.039457 s, 490 M/s - before patch - 1048576000 bytes (0.9 G) copied, 9.146217 s, 109 M/s 1048576000 bytes (0.9 G) copied, 9.997542 s, 100 M/s 1048576000 bytes (0.9 G) copied, 10.109727 s, 99 M/s - after patch - 1048576000 bytes (0.9 G) copied, 2.253441 s, 444 M/s 1048576000 bytes (0.9 G) copied, 2.739764 s, 365 M/s 1048576000 bytes (0.9 G) copied, 2.185649 s, 458 M/s Signed-off-by: Daeho Jeong <daehoje...@google.com> --- fs/f2fs/compress.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 6e7db450006c..46b7e359f313 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -554,6 +554,8 @@ static void f2fs_compress_free_page(struct page *page) mempool_free(page, compress_page_pool); } +#define MAX_VMAP_RETRIES 3 + static int f2fs_compress_pages(struct compress_ctx *cc) { struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode); @@ -590,13 +592,23 @@ static int f2fs_compress_pages(struct compress_ctx *cc) } } - cc->rbuf = vmap(cc->rpages, cc->cluster_size, VM_MAP, PAGE_KERNEL_RO); + for (i = 0; i < MAX_VMAP_RETRIES; i++) { + cc->rbuf = vm_map_ram(cc->rpages, cc->cluster_size, -1); + if (cc->rbuf) + break; + vm_unmap_aliases(); + } if (!cc->rbuf) { ret = -ENOMEM; goto out_free_cpages; } - cc->cbuf = vmap(cc->cpages, cc->nr_cpages, VM_MAP, PAGE_KERNEL); + for (i = 0; i < MAX_VMAP_RETRIES; i++) { + cc->cbuf = vm_map_ram(cc->cpages, cc->nr_cpages, -1); + if (cc->cbuf) + break; + vm_unmap_aliases(); + } if (!cc->cbuf) { ret = -ENOMEM; goto out_vunmap_rbuf; @@ -624,8 +636,8 @@ static int f2fs_compress_pages(struct compress_ctx *cc) memset(&cc->cbuf->cdata[cc->clen], 0, (nr_cpages * PAGE_SIZE) - (cc->clen + COMPRESS_HEADER_SIZE)); - vunmap(cc->cbuf); - vunmap(cc->rbuf); + vm_unmap_ram(cc->cbuf, cc->nr_cpages); + vm_unmap_ram(cc->rbuf, cc->cluster_size); for (i = nr_cpages; i < cc->nr_cpages; i++) { f2fs_compress_free_page(cc->cpages[i]); @@ -642,9 +654,9 @@ static int f2fs_compress_pages(struct compress_ctx *cc) return 0; out_vunmap_cbuf: - vunmap(cc->cbuf); + vm_unmap_ram(cc->cbuf, cc->nr_cpages); out_vunmap_rbuf: - vunmap(cc->rbuf); + vm_unmap_ram(cc->rbuf, cc->cluster_size); out_free_cpages: for (i = 0; i < cc->nr_cpages; i++) { if (cc->cpages[i]) @@ -715,13 +727,23 @@ void f2fs_decompress_pages(struct bio *bio, struct page *page, bool verity) goto out_free_dic; } - dic->rbuf = vmap(dic->tpages, dic->cluster_size, VM_MAP, PAGE_KERNEL); + for (i = 0; i < MAX_VMAP_RETRIES; i++) { + dic->rbuf = vm_map_ram(dic->tpages, dic->cluster_size, -1); + if (dic->rbuf) + break; + vm_unmap_aliases(); + } if (!dic->rbuf) { ret = -ENOMEM; goto destroy_decompress_ctx; } - dic->cbuf = vmap(dic->cpages, dic->nr_cpages, VM_MAP, PAGE_KERNEL_RO); + for (i = 0; i < MAX_VMAP_RETRIES; i++) { + dic->cbuf = vm_map_ram(dic->cpages, dic->nr_cpages, -1); + if (dic->cbuf) + break; + vm_unmap_aliases(); + } if (!dic->cbuf) { ret = -ENOMEM; goto out_vunmap_rbuf; @@ -738,9 +760,9 @@ void f2fs_decompress_pages(struct bio *bio, struct page *page, bool verity) ret = cops->decompress_pages(dic); out_vunmap_cbuf: - vunmap(dic->cbuf); + vm_unmap_ram(dic->cbuf, dic->nr_cpages); out_vunmap_rbuf: - vunmap(dic->rbuf); + vm_unmap_ram(dic->rbuf, dic->cluster_size); destroy_decompress_ctx: if (cops->destroy_decompress_ctx) cops->destroy_decompress_ctx(dic); -- 2.28.0.236.gb10cc79966-goog