Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp565898imw; Thu, 14 Jul 2022 06:49:45 -0700 (PDT) X-Google-Smtp-Source: AGRyM1ty43UOp6wgNSW+YX+d2WRZX/Exy1eW9Taw7Tjd++Cki2yXYunnVDQ6jrh7iLU0w6sIOVdc X-Received: by 2002:a17:907:3e81:b0:726:9615:d14d with SMTP id hs1-20020a1709073e8100b007269615d14dmr8688321ejc.517.1657806584763; Thu, 14 Jul 2022 06:49:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657806584; cv=none; d=google.com; s=arc-20160816; b=zih1A0uknhammsnK1mjFRUf0dP0Dk8EFQvTtq3770PmZdKnV6n1qcJmkpJ7LFWeoHX at7DQeTnNslPDhbUOKrLsNXOiK2+P0lP+47RAlpPSxkV8gU3G7nxo7nHJ7rYK9OMs56y WNFXKDcnkrc3d5FydwqSoVY/Ge68SHqMosgDxwBQoRBEK7q3wunLdfYzzNTk3OX7Rqq+ ISRgCfibWouJ9HWkImG2WykK05aImgqR1nf9+n9YjWaKWjYOSQYrH8FCiaKQG/TkFj1N pI54LpKBgFgkRa9CgoPxesvkRMOHxvR9rkMOohNN7VQPax+F8pre6x+AcpGQUxE5dj0A oUgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=p97btEBT8EqhF8EGSVQmi9yDcop12jRKyJRnbzQJssc=; b=tdoVIYk9idfke+/q1TF17m+msy4UdlGIPwTHHbwvjq8tB3m8MNX72i/1XGrGC39FTh TEXKa2NQybZ1yG6b+rJAG52vht2+QWVMIxyG8Q5Tdj+r6JPQYSXeTtRzGhKn9yyDSy1a amfVR5I3SOFIuBTzJwmAX00TxdHGGVs3ZBv9tRqHBimd1XnmaZ6o8rXp2OODh6+V+Lg5 CDQIHMZ1LKtBWMNiCl/Aa/oU1PFr4G84IhNdVKJyqU1Qq3tztmJMoIgdFITLA1QzQNX6 rycSSL8MCgaL1locd+02aINLOhI+QEpDdD1vaUaPIWf5TSGamaIBxGvoF8v7bvBTOpOj Jtow== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id hp23-20020a1709073e1700b00726e0ea1733si2300808ejc.993.2022.07.14.06.49.19; Thu, 14 Jul 2022 06:49:44 -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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239800AbiGNNVg (ORCPT + 99 others); Thu, 14 Jul 2022 09:21:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47290 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239609AbiGNNVO (ORCPT ); Thu, 14 Jul 2022 09:21:14 -0400 Received: from out30-130.freemail.mail.aliyun.com (out30-130.freemail.mail.aliyun.com [115.124.30.130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0D7ED5D5B1 for ; Thu, 14 Jul 2022 06:21:12 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R141e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046049;MF=hsiangkao@linux.alibaba.com;NM=1;PH=DS;RN=4;SR=0;TI=SMTPD_---0VJJkPKY_1657804869; Received: from e18g06460.et15sqa.tbsite.net(mailfrom:hsiangkao@linux.alibaba.com fp:SMTPD_---0VJJkPKY_1657804869) by smtp.aliyun-inc.com; Thu, 14 Jul 2022 21:21:10 +0800 From: Gao Xiang To: linux-erofs@lists.ozlabs.org, Chao Yu Cc: LKML , Gao Xiang Subject: [PATCH 08/16] erofs: rework online page handling Date: Thu, 14 Jul 2022 21:20:43 +0800 Message-Id: <20220714132051.46012-9-hsiangkao@linux.alibaba.com> X-Mailer: git-send-email 2.24.4 In-Reply-To: <20220714132051.46012-1-hsiangkao@linux.alibaba.com> References: <20220714132051.46012-1-hsiangkao@linux.alibaba.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,UNPARSEABLE_RELAY,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 Since all decompressed offsets have been integrated to bvecs[], this patch avoids all sub-indexes so that page->private only includes a part count and an eio flag, thus in the future folio->private can have the same meaning. In addition, PG_error will not be used anymore after this patch and we're heading to use page->private (later folio->private) and page->mapping (later folio->mapping) only. Signed-off-by: Gao Xiang --- fs/erofs/zdata.c | 51 ++++++++++++++---------------------- fs/erofs/zdata.h | 68 ++++++++++++++---------------------------------- 2 files changed, 38 insertions(+), 81 deletions(-) diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index f2e3f07baad7..9065e160d6a6 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -743,7 +743,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, map->m_llen = 0; err = z_erofs_map_blocks_iter(inode, map, 0); if (err) - goto err_out; + goto out; } else { if (fe->pcl) goto hitted; @@ -755,7 +755,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, err = z_erofs_collector_begin(fe); if (err) - goto err_out; + goto out; if (z_erofs_is_inline_pcluster(fe->pcl)) { void *mp; @@ -766,7 +766,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, err = PTR_ERR(mp); erofs_err(inode->i_sb, "failed to get inline page, err %d", err); - goto err_out; + goto out; } get_page(fe->map.buf.page); WRITE_ONCE(fe->pcl->compressed_bvecs[0].page, @@ -823,16 +823,15 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, if (err) { DBG_BUGON(err == -EAGAIN && fe->candidate_bvpage); - goto err_out; + goto out; } - index = page->index - (map->m_la >> PAGE_SHIFT); - - z_erofs_onlinepage_fixup(page, index, true); - + z_erofs_onlinepage_split(page); /* bump up the number of spiltted parts of a page */ ++spiltted; + /* also update nr_pages */ + index = page->index - (map->m_la >> PAGE_SHIFT); fe->pcl->nr_pages = max_t(pgoff_t, fe->pcl->nr_pages, index + 1); next_part: /* can be used for verification */ @@ -843,16 +842,13 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, goto repeat; out: + if (err) + z_erofs_page_mark_eio(page); z_erofs_onlinepage_endio(page); erofs_dbg("%s, finish page: %pK spiltted: %u map->m_llen %llu", __func__, page, spiltted, map->m_llen); return err; - - /* if some error occurred while processing this page */ -err_out: - SetPageError(page); - goto out; } static bool z_erofs_get_sync_decompress_policy(struct erofs_sb_info *sbi, @@ -901,7 +897,7 @@ static int z_erofs_parse_out_bvecs(struct z_erofs_pcluster *pcl, */ if (pages[pagenr]) { DBG_BUGON(1); - SetPageError(pages[pagenr]); + z_erofs_page_mark_eio(pages[pagenr]); z_erofs_onlinepage_endio(pages[pagenr]); err = -EFSCORRUPTED; } @@ -957,19 +953,13 @@ static struct page **z_erofs_parse_in_bvecs(struct erofs_sb_info *sbi, DBG_BUGON(pgnr >= pcl->nr_pages); if (pages[pgnr]) { DBG_BUGON(1); - SetPageError(pages[pgnr]); + z_erofs_page_mark_eio(pages[pgnr]); z_erofs_onlinepage_endio(pages[pgnr]); err = -EFSCORRUPTED; } pages[pgnr] = page; *overlapped = true; } - - /* PG_error needs checking for all non-managed pages */ - if (PageError(page)) { - DBG_BUGON(PageUptodate(page)); - err = -EIO; - } } if (err) { @@ -981,7 +971,7 @@ static struct page **z_erofs_parse_in_bvecs(struct erofs_sb_info *sbi, static int z_erofs_decompress_pcluster(struct super_block *sb, struct z_erofs_pcluster *pcl, - struct page **pagepool) + struct page **pagepool, int err) { struct erofs_sb_info *const sbi = EROFS_SB(sb); unsigned int pclusterpages = z_erofs_pclusterpages(pcl); @@ -990,7 +980,6 @@ static int z_erofs_decompress_pcluster(struct super_block *sb, struct page **pages, **compressed_pages, *page; bool overlapped, partial; - int err; might_sleep(); DBG_BUGON(!READ_ONCE(pcl->nr_pages)); @@ -1090,10 +1079,8 @@ static int z_erofs_decompress_pcluster(struct super_block *sb, /* recycle all individual short-lived pages */ if (z_erofs_put_shortlivedpage(pagepool, page)) continue; - - if (err < 0) - SetPageError(page); - + if (err) + z_erofs_page_mark_eio(page); z_erofs_onlinepage_endio(page); } @@ -1129,7 +1116,8 @@ static void z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io, pcl = container_of(owned, struct z_erofs_pcluster, next); owned = READ_ONCE(pcl->next); - z_erofs_decompress_pcluster(io->sb, pcl, pagepool); + z_erofs_decompress_pcluster(io->sb, pcl, pagepool, + io->eio ? -EIO : 0); erofs_workgroup_put(&pcl->obj); } } @@ -1233,7 +1221,6 @@ static struct page *pickup_page_for_submission(struct z_erofs_pcluster *pcl, if (page->mapping == mc) { WRITE_ONCE(pcl->compressed_bvecs[nr].page, page); - ClearPageError(page); if (!PagePrivate(page)) { /* * impossible to be !PagePrivate(page) for @@ -1305,6 +1292,7 @@ jobqueue_init(struct super_block *sb, q = fgq; init_completion(&fgq->u.done); atomic_set(&fgq->pending_bios, 0); + q->eio = true; } q->sb = sb; q->head = Z_EROFS_PCLUSTER_TAIL_CLOSED; @@ -1365,15 +1353,14 @@ static void z_erofs_decompressqueue_endio(struct bio *bio) DBG_BUGON(PageUptodate(page)); DBG_BUGON(z_erofs_page_is_invalidated(page)); - if (err) - SetPageError(page); - if (erofs_page_is_managed(EROFS_SB(q->sb), page)) { if (!err) SetPageUptodate(page); unlock_page(page); } } + if (err) + q->eio = true; z_erofs_decompress_kickoff(q, tagptr_unfold_tags(t), -1); bio_put(bio); } diff --git a/fs/erofs/zdata.h b/fs/erofs/zdata.h index a70f1b73e901..852da31e2e91 100644 --- a/fs/erofs/zdata.h +++ b/fs/erofs/zdata.h @@ -109,6 +109,8 @@ struct z_erofs_decompressqueue { struct completion done; struct work_struct work; } u; + + bool eio; }; static inline bool z_erofs_is_inline_pcluster(struct z_erofs_pcluster *pcl) @@ -123,38 +125,17 @@ static inline unsigned int z_erofs_pclusterpages(struct z_erofs_pcluster *pcl) return pcl->pclusterpages; } -#define Z_EROFS_ONLINEPAGE_COUNT_BITS 2 -#define Z_EROFS_ONLINEPAGE_COUNT_MASK ((1 << Z_EROFS_ONLINEPAGE_COUNT_BITS) - 1) -#define Z_EROFS_ONLINEPAGE_INDEX_SHIFT (Z_EROFS_ONLINEPAGE_COUNT_BITS) - /* - * waiters (aka. ongoing_packs): # to unlock the page - * sub-index: 0 - for partial page, >= 1 full page sub-index + * bit 31: I/O error occurred on this page + * bit 0 - 30: remaining parts to complete this page */ -typedef atomic_t z_erofs_onlinepage_t; - -/* type punning */ -union z_erofs_onlinepage_converter { - z_erofs_onlinepage_t *o; - unsigned long *v; -}; - -static inline unsigned int z_erofs_onlinepage_index(struct page *page) -{ - union z_erofs_onlinepage_converter u; - - DBG_BUGON(!PagePrivate(page)); - u.v = &page_private(page); - - return atomic_read(u.o) >> Z_EROFS_ONLINEPAGE_INDEX_SHIFT; -} +#define Z_EROFS_PAGE_EIO (1 << 31) static inline void z_erofs_onlinepage_init(struct page *page) { union { - z_erofs_onlinepage_t o; + atomic_t o; unsigned long v; - /* keep from being unlocked in advance */ } u = { .o = ATOMIC_INIT(1) }; set_page_private(page, u.v); @@ -162,45 +143,34 @@ static inline void z_erofs_onlinepage_init(struct page *page) SetPagePrivate(page); } -static inline void z_erofs_onlinepage_fixup(struct page *page, - uintptr_t index, bool down) +static inline void z_erofs_onlinepage_split(struct page *page) { - union z_erofs_onlinepage_converter u = { .v = &page_private(page) }; - int orig, orig_index, val; - -repeat: - orig = atomic_read(u.o); - orig_index = orig >> Z_EROFS_ONLINEPAGE_INDEX_SHIFT; - if (orig_index) { - if (!index) - return; + atomic_inc((atomic_t *)&page->private); +} - DBG_BUGON(orig_index != index); - } +static inline void z_erofs_page_mark_eio(struct page *page) +{ + int orig; - val = (index << Z_EROFS_ONLINEPAGE_INDEX_SHIFT) | - ((orig & Z_EROFS_ONLINEPAGE_COUNT_MASK) + (unsigned int)down); - if (atomic_cmpxchg(u.o, orig, val) != orig) - goto repeat; + do { + orig = atomic_read((atomic_t *)&page->private); + } while (atomic_cmpxchg((atomic_t *)&page->private, orig, + orig | Z_EROFS_PAGE_EIO) != orig); } static inline void z_erofs_onlinepage_endio(struct page *page) { - union z_erofs_onlinepage_converter u; unsigned int v; DBG_BUGON(!PagePrivate(page)); - u.v = &page_private(page); - - v = atomic_dec_return(u.o); - if (!(v & Z_EROFS_ONLINEPAGE_COUNT_MASK)) { + v = atomic_dec_return((atomic_t *)&page->private); + if (!(v & ~Z_EROFS_PAGE_EIO)) { set_page_private(page, 0); ClearPagePrivate(page); - if (!PageError(page)) + if (!(v & Z_EROFS_PAGE_EIO)) SetPageUptodate(page); unlock_page(page); } - erofs_dbg("%s, page %p value %x", __func__, page, atomic_read(u.o)); } #define Z_EROFS_VMAP_ONSTACK_PAGES \ -- 2.24.4