Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp3512238imw; Mon, 18 Jul 2022 09:22:22 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vpelJchYuKV9IbOePsSdBugYUnYRXhiKEZGWF7jEL0rHhpyfsXjQTc/UZ2F1MaD1RVY+MW X-Received: by 2002:a05:6808:1b29:b0:33a:7bea:7b1c with SMTP id bx41-20020a0568081b2900b0033a7bea7b1cmr1908742oib.275.1658161342687; Mon, 18 Jul 2022 09:22:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658161342; cv=none; d=google.com; s=arc-20160816; b=IN9wAcX9a/45J09E+GD9j0v2zLM2tLjThdsVSjrUumhELxbbdlJDMpW4LERfTIVFx8 iqeI0j+n3DUAsn9gFpAtQCrO6SBCjcdiWai0o+BI27+7wweK1UMxtTOV/5U/+Pg7KDiC B4zFVwBB3hpVSKCVHYe8clChdEhNA4y1/9nNLr6JSur96mxKa/zHBCDIPTjY5ClMBlKg uO5GQct5Yp2IB+2mM2cmhy6ksV3yEUsCJdZOUKMq12jv1bgnDnZjvQ6WIfBJDG3pVBK6 YeAHSRGu/KRy6Ey3YKK3A2hmvp/rHFlj+fJOYjxZnq9C1jvK7Va+zhQjTjGIcq+RvlyJ QTng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=Dk+xyKAh8stH+gJuo+HC8r0ztTYGaAoCfa5wLQ+egZs=; b=LHMvgEHZimfQum4McllvMl7m8eVVBtaI5LxnRSQO2Xr60pu115t9MDgJSkZVZPokOq dZ+kVABxJXBaLFhS2zQXVv4Bhhsw4y6eXxdY7zWkZbEp1XpyrS/Gb+WwhZtlLql4wqqB qGReanh7FesYzqLGp+Hs2al89QxOp+euGLTEa6wbsnxU2pbBLJC5eldcfvdrwuL9eT8Q sLpHqHyJUEl2v/uy+iT4NW7MKQDxEmkmHW1okvlUI5jFoeW12JGjOAnIv4RHl7XbIjP6 u1qdd7ZkmZRek9sykucfP+w1wOOP9VWUjWqNus1PZcHDdgwAXESmcg37sC+5Ig/tw7Vt uJ6g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=DUQrJjUS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bj21-20020a056808199500b00339f16b29d6si4865177oib.146.2022.07.18.09.22.08; Mon, 18 Jul 2022 09:22:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=DUQrJjUS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234595AbiGRPs1 (ORCPT + 99 others); Mon, 18 Jul 2022 11:48:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229639AbiGRPsZ (ORCPT ); Mon, 18 Jul 2022 11:48:25 -0400 Received: from mail-yb1-xb2a.google.com (mail-yb1-xb2a.google.com [IPv6:2607:f8b0:4864:20::b2a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0403229812 for ; Mon, 18 Jul 2022 08:48:24 -0700 (PDT) Received: by mail-yb1-xb2a.google.com with SMTP id 64so21475311ybt.12 for ; Mon, 18 Jul 2022 08:48:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=Dk+xyKAh8stH+gJuo+HC8r0ztTYGaAoCfa5wLQ+egZs=; b=DUQrJjUS1vTJg0/7gmL3+ZZ09OZv5kJx1NHFSPmgxURGXOwwOfxvl9Oh9/Zv4joJmW Tkis/ZmxFeMb2+jT8mlpkcNBErCEpM/sQaqURNSUjkSta5u0YqAgZTK2Htb/koFfthIs mlQVJi1FDuE03mHwQ8saps8KelbJpleHVYxadl3bdPMPl9WVXqci9GCJkYlycox6Gtku LYYiuyzKwyWx2JQwRuOjEvMwhNT9/+EGxYE+Ig1aMaklPOLLIk5/7YGGYS7g0pXKz2Bs /uQW5o0bP3Q1J4lTeLkrUAouPztFCSKgi2zRpWPSBVXoCa8PyjqvF6bV4c0zQyDfjQm5 VhBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=Dk+xyKAh8stH+gJuo+HC8r0ztTYGaAoCfa5wLQ+egZs=; b=7NzZvYkw03pW5K8TM7WWljJgrRWhyMkkK/nyDRgyPg1oOB0GO+RSETJTqbsIxQmBev BOFhr1HtUBuVSQQuldTvS+HarUbpvOeDN8iEw0zNSXb7LFRkaAdw0ZBVavGYMMyeKxcs 2tbeeBn6cTtWUBbJNcsedbqqLZKw5nvjyqpwY5G74xzWwaqjY32AgvMN6ESr3SMoYOUd O58tF6YaMGcNkwbYyDA5S7PFb1QG+mL6A8EH+siDuFaDOP9aFWV5bRqbQSMtaROdLzPQ XbzNhXcs/B2THWlStuYNurKjREPCsYk9GSCpMVDmNEGpYkHk+Kim47zmDmkga8Hxdgje O0VA== X-Gm-Message-State: AJIora/yVMZ1BsBhnRvbek2uXz+WYCkp1JJF3iE/XuPYsm4AN+35npsr AZVs1CB6buNwslKHeQhyDwhC3NRXyY7XdTEZrZfAiTx3g5s= X-Received: by 2002:a25:d0d6:0:b0:670:1b8:cc9a with SMTP id h205-20020a25d0d6000000b0067001b8cc9amr13721194ybg.232.1658159302954; Mon, 18 Jul 2022 08:48:22 -0700 (PDT) MIME-Version: 1.0 References: <20220620173843.1462198-1-daeho43@gmail.com> <20220620173843.1462198-2-daeho43@gmail.com> <279827c1-734b-829c-72ca-aa5233b8165c@kernel.org> In-Reply-To: <279827c1-734b-829c-72ca-aa5233b8165c@kernel.org> From: Daeho Jeong Date: Mon, 18 Jul 2022 08:47:45 -0700 Message-ID: Subject: Re: [f2fs-dev] [PATCH 2/2] f2fs: handle decompress only post processing in softirq To: Chao Yu Cc: Jaegeuk Kim , Daeho Jeong , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-17.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Jul 16, 2022 at 8:22 PM Chao Yu wrote: > > On 2022/6/22 0:07, Jaegeuk Kim wrote: > > Can we do like this which has no functional change but refactored > > some functions? > > > > --- > > fs/f2fs/compress.c | 208 ++++++++++++++++++++++++++++----------------- > > fs/f2fs/data.c | 52 ++++++++---- > > fs/f2fs/f2fs.h | 17 ++-- > > 3 files changed, 172 insertions(+), 105 deletions(-) > > > > diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c > > index fa237e5c7173..494ce3634b62 100644 > > --- a/fs/f2fs/compress.c > > +++ b/fs/f2fs/compress.c > > @@ -729,28 +729,18 @@ static int f2fs_compress_pages(struct compress_ctx *cc) > > return ret; > > } > > > > -void f2fs_decompress_cluster(struct decompress_io_ctx *dic) > > +static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic, bool end_io) > > { > > - struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); > > - struct f2fs_inode_info *fi = F2FS_I(dic->inode); > > const struct f2fs_compress_ops *cops = > > - f2fs_cops[fi->i_compress_algorithm]; > > - int ret; > > + f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm]; > > int i; > > > > - trace_f2fs_decompress_pages_start(dic->inode, dic->cluster_idx, > > - dic->cluster_size, fi->i_compress_algorithm); > > - > > - if (dic->failed) { > > - ret = -EIO; > > - goto out_end_io; > > - } > > + if (!(end_io ^ f2fs_low_mem_mode(F2FS_I_SB(dic->inode)))) > > How about using allow_decompress_in_softirq() to wrap !f2fs_low_mem_mode() > to improve readability? > > > + return 0; > > > > dic->tpages = page_array_alloc(dic->inode, dic->cluster_size); > > - if (!dic->tpages) { > > - ret = -ENOMEM; > > - goto out_end_io; > > - } > > + if (!dic->tpages) > > + return 1; > > return -ENOMEM instead of magic number. The callers already change the error number to ENOMEM when it gets 1. This is the same flow in the previous code. Do you want to change this? > > > > > for (i = 0; i < dic->cluster_size; i++) { > > if (dic->rpages[i]) { > > @@ -759,28 +749,100 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic) > > } > > > > dic->tpages[i] = f2fs_compress_alloc_page(); > > - if (!dic->tpages[i]) { > > - ret = -ENOMEM; > > - goto out_end_io; > > - } > > + if (!dic->tpages[i]) > > + return 1; > > Ditto, > > > } > > > > + dic->rbuf = f2fs_vmap(dic->tpages, dic->cluster_size); > > + if (!dic->rbuf) > > + return 1; > > Ditto, > > > + > > + dic->cbuf = f2fs_vmap(dic->cpages, dic->nr_cpages); > > + if (!dic->cbuf) > > + return 1; > > Ditto, > > > + > > + cops = f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm]; > > No need to assign cops again? Ack > > > if (cops->init_decompress_ctx) { > > - ret = cops->init_decompress_ctx(dic); > > + int ret = cops->init_decompress_ctx(dic); > > + > > if (ret) > > - goto out_end_io; > > + return 1; > > How about returning ret here instead of magic number? > > > } > > > > - dic->rbuf = f2fs_vmap(dic->tpages, dic->cluster_size); > > - if (!dic->rbuf) { > > - ret = -ENOMEM; > > - goto out_destroy_decompress_ctx; > > + return 0; > > +} > > + > > +static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic, > > + bool bypass_destroy_callback, bool end_io) > > +{ > > + const struct f2fs_compress_ops *cops = > > + f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm]; > > + > > + if (end_io ^ f2fs_low_mem_mode(F2FS_I_SB(dic->inode))) > > + return; > > + > > + if (!bypass_destroy_callback && cops->destroy_decompress_ctx) > > + cops->destroy_decompress_ctx(dic); > > + > > + if (dic->cbuf) > > + vm_unmap_ram(dic->cbuf, dic->nr_cpages); > > + > > + if (dic->rbuf) > > + vm_unmap_ram(dic->rbuf, dic->cluster_size); > > +} > > + > > +static void f2fs_free_dic(struct decompress_io_ctx *dic, > > + bool bypass_destroy_callback) > > +{ > > + int i; > > + > > + f2fs_release_decomp_mem(dic, bypass_destroy_callback, false); > > + > > + if (dic->tpages) { > > + for (i = 0; i < dic->cluster_size; i++) { > > + if (dic->rpages[i]) > > + continue; > > + if (!dic->tpages[i]) > > + continue; > > + f2fs_compress_free_page(dic->tpages[i]); > > + } > > + page_array_free(dic->inode, dic->tpages, dic->cluster_size); > > } > > > > - dic->cbuf = f2fs_vmap(dic->cpages, dic->nr_cpages); > > - if (!dic->cbuf) { > > + if (dic->cpages) { > > + for (i = 0; i < dic->nr_cpages; i++) { > > + if (!dic->cpages[i]) > > + continue; > > + f2fs_compress_free_page(dic->cpages[i]); > > + } > > + page_array_free(dic->inode, dic->cpages, dic->nr_cpages); > > + } > > + > > + page_array_free(dic->inode, dic->rpages, dic->nr_rpages); > > + kmem_cache_free(dic_entry_slab, dic); > > +} > > + > > +void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task) > > +{ > > + struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); > > + struct f2fs_inode_info *fi = F2FS_I(dic->inode); > > + const struct f2fs_compress_ops *cops = > > + f2fs_cops[fi->i_compress_algorithm]; > > + bool bypass_callback = false; > > + int ret; > > + > > + trace_f2fs_decompress_pages_start(dic->inode, dic->cluster_idx, > > + dic->cluster_size, fi->i_compress_algorithm); > > + > > + if (dic->failed) { > > + ret = -EIO; > > + goto out_end_io; > > + } > > + > > + if (f2fs_prepare_decomp_mem(dic, true)) { > > + bypass_callback = true; > > ret = -ENOMEM; > > - goto out_vunmap_rbuf; > > + goto out_release; > > } > > > > dic->clen = le32_to_cpu(dic->cbuf->clen); > > @@ -788,7 +850,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic) > > > > if (dic->clen > PAGE_SIZE * dic->nr_cpages - COMPRESS_HEADER_SIZE) { > > ret = -EFSCORRUPTED; > > - goto out_vunmap_cbuf; > > + goto out_release; > > } > > > > ret = cops->decompress_pages(dic); > > @@ -809,17 +871,13 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic) > > } > > } > > > > -out_vunmap_cbuf: > > - vm_unmap_ram(dic->cbuf, dic->nr_cpages); > > -out_vunmap_rbuf: > > - vm_unmap_ram(dic->rbuf, dic->cluster_size); > > -out_destroy_decompress_ctx: > > - if (cops->destroy_decompress_ctx) > > - cops->destroy_decompress_ctx(dic); > > +out_release: > > + f2fs_release_decomp_mem(dic, bypass_callback, true); > > + > > out_end_io: > > trace_f2fs_decompress_pages_end(dic->inode, dic->cluster_idx, > > dic->clen, ret); > > - f2fs_decompress_end_io(dic, ret); > > + f2fs_decompress_end_io(dic, ret, in_task); > > } > > > > /* > > @@ -829,7 +887,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic) > > * (or in the case of a failure, cleans up without actually decompressing). > > */ > > void f2fs_end_read_compressed_page(struct page *page, bool failed, > > - block_t blkaddr) > > + block_t blkaddr, bool in_task) > > { > > struct decompress_io_ctx *dic = > > (struct decompress_io_ctx *)page_private(page); > > @@ -839,12 +897,12 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed, > > > > if (failed) > > WRITE_ONCE(dic->failed, true); > > - else if (blkaddr) > > + else if (blkaddr && in_task) > > f2fs_cache_compressed_page(sbi, page, > > dic->inode->i_ino, blkaddr); > > > > if (atomic_dec_and_test(&dic->remaining_pages)) > > - f2fs_decompress_cluster(dic); > > + f2fs_decompress_cluster(dic, in_task); > > } > > > > static bool is_page_in_cluster(struct compress_ctx *cc, pgoff_t index) > > @@ -1552,16 +1610,14 @@ int f2fs_write_multi_pages(struct compress_ctx *cc, > > return err; > > } > > > > -static void f2fs_free_dic(struct decompress_io_ctx *dic); > > - > > struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) > > { > > struct decompress_io_ctx *dic; > > pgoff_t start_idx = start_idx_of_cluster(cc); > > + struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode); > > int i; > > > > - dic = f2fs_kmem_cache_alloc(dic_entry_slab, GFP_F2FS_ZERO, > > - false, F2FS_I_SB(cc->inode)); > > + dic = f2fs_kmem_cache_alloc(dic_entry_slab, GFP_F2FS_ZERO, false, sbi); > > if (!dic) > > return ERR_PTR(-ENOMEM); > > > > @@ -1602,52 +1658,43 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) > > dic->cpages[i] = page; > > } > > > > + if (f2fs_prepare_decomp_mem(dic, false)) > > + goto out_free; > > + > > return dic; > > > > out_free: > > - f2fs_free_dic(dic); > > + f2fs_free_dic(dic, true); > > return ERR_PTR(-ENOMEM); > > } > > > > -static void f2fs_free_dic(struct decompress_io_ctx *dic) > > +static void f2fs_late_free_dic(struct work_struct *work) > > { > > - int i; > > - > > - if (dic->tpages) { > > - for (i = 0; i < dic->cluster_size; i++) { > > - if (dic->rpages[i]) > > - continue; > > - if (!dic->tpages[i]) > > - continue; > > - f2fs_compress_free_page(dic->tpages[i]); > > - } > > - page_array_free(dic->inode, dic->tpages, dic->cluster_size); > > - } > > - > > - if (dic->cpages) { > > - for (i = 0; i < dic->nr_cpages; i++) { > > - if (!dic->cpages[i]) > > - continue; > > - f2fs_compress_free_page(dic->cpages[i]); > > - } > > - page_array_free(dic->inode, dic->cpages, dic->nr_cpages); > > - } > > + struct decompress_io_ctx *dic = > > + container_of(work, struct decompress_io_ctx, free_work); > > > > - page_array_free(dic->inode, dic->rpages, dic->nr_rpages); > > - kmem_cache_free(dic_entry_slab, dic); > > + f2fs_free_dic(dic, false); > > } > > > > -static void f2fs_put_dic(struct decompress_io_ctx *dic) > > +static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task) > > { > > - if (refcount_dec_and_test(&dic->refcnt)) > > - f2fs_free_dic(dic); > > + if (refcount_dec_and_test(&dic->refcnt)) { > > + if (in_task) { > > + f2fs_free_dic(dic, false); > > + } else { > > + INIT_WORK(&dic->free_work, f2fs_late_free_dic); > > + queue_work(F2FS_I_SB(dic->inode)->post_read_wq, > > + &dic->free_work); > > + } > > + } > > } > > > > /* > > * Update and unlock the cluster's pagecache pages, and release the reference to > > * the decompress_io_ctx that was being held for I/O completion. > > */ > > -static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) > > +static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed, > > + bool in_task) > > { > > int i; > > > > @@ -1668,7 +1715,7 @@ static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) > > unlock_page(rpage); > > } > > > > - f2fs_put_dic(dic); > > + f2fs_put_dic(dic, in_task); > > } > > > > static void f2fs_verify_cluster(struct work_struct *work) > > @@ -1685,14 +1732,15 @@ static void f2fs_verify_cluster(struct work_struct *work) > > SetPageError(rpage); > > } > > > > - __f2fs_decompress_end_io(dic, false); > > + __f2fs_decompress_end_io(dic, false, true); > > } > > > > /* > > * This is called when a compressed cluster has been decompressed > > * (or failed to be read and/or decompressed). > > */ > > -void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) > > +void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed, > > + bool in_task) > > { > > if (!failed && dic->need_verity) { > > /* > > @@ -1704,7 +1752,7 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) > > INIT_WORK(&dic->verity_work, f2fs_verify_cluster); > > fsverity_enqueue_verify_work(&dic->verity_work); > > } else { > > - __f2fs_decompress_end_io(dic, failed); > > + __f2fs_decompress_end_io(dic, failed, in_task); > > } > > } > > > > @@ -1713,12 +1761,12 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) > > * > > * This is called when the page is no longer needed and can be freed. > > */ > > -void f2fs_put_page_dic(struct page *page) > > +void f2fs_put_page_dic(struct page *page, bool in_task) > > { > > struct decompress_io_ctx *dic = > > (struct decompress_io_ctx *)page_private(page); > > > > - f2fs_put_dic(dic); > > + f2fs_put_dic(dic, in_task); > > } > > > > /* > > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > > index 7fcbcf979737..c448c3ee7ac3 100644 > > --- a/fs/f2fs/data.c > > +++ b/fs/f2fs/data.c > > @@ -119,7 +119,7 @@ struct bio_post_read_ctx { > > block_t fs_blkaddr; > > }; > > > > -static void f2fs_finish_read_bio(struct bio *bio) > > +static void f2fs_finish_read_bio(struct bio *bio, bool in_task) > > { > > struct bio_vec *bv; > > struct bvec_iter_all iter_all; > > @@ -133,8 +133,9 @@ static void f2fs_finish_read_bio(struct bio *bio) > > > > if (f2fs_is_compressed_page(page)) { > > if (bio->bi_status) > > - f2fs_end_read_compressed_page(page, true, 0); > > - f2fs_put_page_dic(page); > > + f2fs_end_read_compressed_page(page, true, 0, > > + in_task); > > + f2fs_put_page_dic(page, in_task); > > continue; > > } > > > > @@ -191,7 +192,7 @@ static void f2fs_verify_bio(struct work_struct *work) > > fsverity_verify_bio(bio); > > } > > > > - f2fs_finish_read_bio(bio); > > + f2fs_finish_read_bio(bio, true); > > } > > > > /* > > @@ -203,7 +204,7 @@ static void f2fs_verify_bio(struct work_struct *work) > > * can involve reading verity metadata pages from the file, and these verity > > * metadata pages may be encrypted and/or compressed. > > */ > > -static void f2fs_verify_and_finish_bio(struct bio *bio) > > +static void f2fs_verify_and_finish_bio(struct bio *bio, bool in_task) > > { > > struct bio_post_read_ctx *ctx = bio->bi_private; > > > > @@ -211,7 +212,7 @@ static void f2fs_verify_and_finish_bio(struct bio *bio) > > INIT_WORK(&ctx->work, f2fs_verify_bio); > > fsverity_enqueue_verify_work(&ctx->work); > > } else { > > - f2fs_finish_read_bio(bio); > > + f2fs_finish_read_bio(bio, in_task); > > } > > } > > > > @@ -224,7 +225,8 @@ static void f2fs_verify_and_finish_bio(struct bio *bio) > > * that the bio includes at least one compressed page. The actual decompression > > * is done on a per-cluster basis, not a per-bio basis. > > */ > > -static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx) > > +static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx, > > + bool in_task) > > { > > struct bio_vec *bv; > > struct bvec_iter_all iter_all; > > @@ -237,7 +239,7 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx) > > /* PG_error was set if decryption failed. */ > > if (f2fs_is_compressed_page(page)) > > f2fs_end_read_compressed_page(page, PageError(page), > > - blkaddr); > > + blkaddr, in_task); > > else > > all_compressed = false; > > > > @@ -262,15 +264,16 @@ static void f2fs_post_read_work(struct work_struct *work) > > fscrypt_decrypt_bio(ctx->bio); > > > > if (ctx->enabled_steps & STEP_DECOMPRESS) > > - f2fs_handle_step_decompress(ctx); > > + f2fs_handle_step_decompress(ctx, true); > > > > - f2fs_verify_and_finish_bio(ctx->bio); > > + f2fs_verify_and_finish_bio(ctx->bio, true); > > } > > > > static void f2fs_read_end_io(struct bio *bio) > > { > > struct f2fs_sb_info *sbi = F2FS_P_SB(bio_first_page_all(bio)); > > struct bio_post_read_ctx *ctx; > > + bool intask = in_task(); > > Is there any condition that in_task() is true here? Maybe I'm missing > something here.... I think that error handling cases in block layer before submitting bio falls in this. > > Thanks, > > > > > iostat_update_and_unbind_ctx(bio, 0); > > ctx = bio->bi_private; > > @@ -281,16 +284,29 @@ static void f2fs_read_end_io(struct bio *bio) > > } > > > > if (bio->bi_status) { > > - f2fs_finish_read_bio(bio); > > + f2fs_finish_read_bio(bio, intask); > > return; > > } > > > > - if (ctx && (ctx->enabled_steps & (STEP_DECRYPT | STEP_DECOMPRESS))) { > > - INIT_WORK(&ctx->work, f2fs_post_read_work); > > - queue_work(ctx->sbi->post_read_wq, &ctx->work); > > - } else { > > - f2fs_verify_and_finish_bio(bio); > > + if (ctx) { > > + unsigned int enabled_steps = ctx->enabled_steps & > > + (STEP_DECRYPT | STEP_DECOMPRESS); > > + > > + /* > > + * If we have only decompression step between decompression and > > + * decrypt, we don't need post processing for this. > > + */ > > + if (enabled_steps == STEP_DECOMPRESS && > > + !f2fs_low_mem_mode(sbi)) { > > + f2fs_handle_step_decompress(ctx, intask); > > + } else if (enabled_steps) { > > + INIT_WORK(&ctx->work, f2fs_post_read_work); > > + queue_work(ctx->sbi->post_read_wq, &ctx->work); > > + return; > > + } > > } > > + > > + f2fs_verify_and_finish_bio(bio, intask); > > } > > > > static void f2fs_write_end_io(struct bio *bio) > > @@ -2222,7 +2238,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, > > > > if (f2fs_load_compressed_page(sbi, page, blkaddr)) { > > if (atomic_dec_and_test(&dic->remaining_pages)) > > - f2fs_decompress_cluster(dic); > > + f2fs_decompress_cluster(dic, true); > > continue; > > } > > > > @@ -2240,7 +2256,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, > > page->index, for_write); > > if (IS_ERR(bio)) { > > ret = PTR_ERR(bio); > > - f2fs_decompress_end_io(dic, ret); > > + f2fs_decompress_end_io(dic, ret, true); > > f2fs_put_dnode(&dn); > > *bio_ret = NULL; > > return ret; > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > > index fea97093d927..c9a31934b948 100644 > > --- a/fs/f2fs/f2fs.h > > +++ b/fs/f2fs/f2fs.h > > @@ -1588,6 +1588,7 @@ struct decompress_io_ctx { > > void *private; /* payload buffer for specified decompression algorithm */ > > void *private2; /* extra payload buffer */ > > struct work_struct verity_work; /* work to verify the decompressed pages */ > > + struct work_struct free_work; /* work for late free this structure itself */ > > }; > > > > #define NULL_CLUSTER ((unsigned int)(~0)) > > @@ -4166,9 +4167,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page); > > bool f2fs_is_compress_backend_ready(struct inode *inode); > > int f2fs_init_compress_mempool(void); > > void f2fs_destroy_compress_mempool(void); > > -void f2fs_decompress_cluster(struct decompress_io_ctx *dic); > > +void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task); > > void f2fs_end_read_compressed_page(struct page *page, bool failed, > > - block_t blkaddr); > > + block_t blkaddr, bool in_task); > > bool f2fs_cluster_is_empty(struct compress_ctx *cc); > > bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index); > > bool f2fs_all_cluster_page_loaded(struct compress_ctx *cc, struct pagevec *pvec, > > @@ -4187,8 +4188,9 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, > > unsigned nr_pages, sector_t *last_block_in_bio, > > bool is_readahead, bool for_write); > > struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc); > > -void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed); > > -void f2fs_put_page_dic(struct page *page); > > +void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed, > > + bool in_task); > > +void f2fs_put_page_dic(struct page *page, bool in_task); > > unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn); > > int f2fs_init_compress_ctx(struct compress_ctx *cc); > > void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse); > > @@ -4234,13 +4236,14 @@ static inline struct page *f2fs_compress_control_page(struct page *page) > > } > > static inline int f2fs_init_compress_mempool(void) { return 0; } > > static inline void f2fs_destroy_compress_mempool(void) { } > > -static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { } > > +static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic, > > + bool in_task) { } > > static inline void f2fs_end_read_compressed_page(struct page *page, > > - bool failed, block_t blkaddr) > > + bool failed, block_t blkaddr, bool in_task) > > { > > WARN_ON_ONCE(1); > > } > > -static inline void f2fs_put_page_dic(struct page *page) > > +static inline void f2fs_put_page_dic(struct page *page, bool in_task) > > { > > WARN_ON_ONCE(1); > > }