From patchwork Tue May 30 01:18:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 13259063 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F422FC77B7E for ; Tue, 30 May 2023 01:18:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229836AbjE3BSa (ORCPT ); Mon, 29 May 2023 21:18:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229647AbjE3BS3 (ORCPT ); Mon, 29 May 2023 21:18:29 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BE6CCDB for ; Mon, 29 May 2023 18:18:25 -0700 (PDT) Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 7991B1FDDD for ; Tue, 30 May 2023 01:18:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1685409504; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VogHfS6Hpg5PeV9xmuf3aWOXV4y/phRmvYgzwvKizi8=; b=GiTUVb3AjQJU405Rv3qb1IIwmA77uDPhaKcNPJxI4hK6zqfFsT6hIvVlpBWGix6AwLyuUp xFZyB/ivzPEig86md2VdhfCTRh8HKH8p9kvqOZZVqptR54bRHVzjmwrHP9Dpb8xWjf9G0W QIJa45dUMYnrMwDwI0tx2T27vEHndwA= Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap1.suse-dmz.suse.de (Postfix) with ESMTPS id E736C1341B for ; Tue, 30 May 2023 01:18:23 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap1.suse-dmz.suse.de with ESMTPSA id gDLoLd9OdWRIIQAAGKfGzw (envelope-from ) for ; Tue, 30 May 2023 01:18:23 +0000 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH 1/3] btrfs: make alloc_extent_buffer() handle previously uptodate range more efficient for subpage Date: Tue, 30 May 2023 09:18:03 +0800 Message-Id: X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Currently alloc_extent_buffer() would make the extent buffer uptodate if the corresponding pages are also uptodate. But this check is only checking PageUptodate, which is fine for regular cases, but not for subpage cases, as we can have multiple extent buffers in the same page. So here we go btrfs_page_test_uptodate() instead. The old code doesn't cause any problem, but not efficient, as it would cause extra metadata read even if the range is already uptodate. Signed-off-by: Qu Wenruo --- fs/btrfs/extent_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index bbf212c7a43f..9afdcf0c70dd 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3708,7 +3708,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, WARN_ON(btrfs_page_test_dirty(fs_info, p, eb->start, eb->len)); eb->pages[i] = p; - if (!PageUptodate(p)) + if (!btrfs_page_test_uptodate(fs_info, p, eb->start, eb->len)) uptodate = 0; /* From patchwork Tue May 30 01:18:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 13259065 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44FC2C77B7A for ; Tue, 30 May 2023 01:18:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229863AbjE3BSb (ORCPT ); Mon, 29 May 2023 21:18:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229672AbjE3BS3 (ORCPT ); Mon, 29 May 2023 21:18:29 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2687DDE for ; Mon, 29 May 2023 18:18:27 -0700 (PDT) Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 5E50821A2E for ; Tue, 30 May 2023 01:18:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1685409505; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5H5u0t0nx4dMqk0Q92K2zA80bt2OXfTw4ANhNdg4bSU=; b=jWN+JZrar1yZJC9HDO/kX/oqSY23DlAiPPxWsRYM6BZaeFq4VgFf5f8ukGjdonS+M1JBz7 6m1xHn7RFSagz1XD0dDhuHAnfu6tHIMFkFx6Vie9VmNzhq3kdb437OMkknlRE61BJJDY/q DcMWL1bhnlqq9t5Jlo1ta8Go7NyYtPE= Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap1.suse-dmz.suse.de (Postfix) with ESMTPS id CB96D1341B for ; Tue, 30 May 2023 01:18:24 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap1.suse-dmz.suse.de with ESMTPSA id 6H8lJ+BOdWRIIQAAGKfGzw (envelope-from ) for ; Tue, 30 May 2023 01:18:24 +0000 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH 2/3] btrfs: use the same @uptodate variable for end_bio_extent_readpage() Date: Tue, 30 May 2023 09:18:04 +0800 Message-Id: <65fed3703d077362b9a7b3ec393452c40b6895db.1685408905.git.wqu@suse.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In function end_bio_extent_readpage() we call endio_readpage_release_extent() to unlock the extent io tree. However we pass PageUptodate(page) as @uptodate parameter for it, while for previous end_page_read() call, we use a dedicated @uptodate local variable. This is not a big deal, as even for subpage cases, either the bio only covers part of the page, then the @uptodate is always false, and the subpage ranges can still be merged. But for the sake of consistency, always use @uptodate variable when possible. Signed-off-by: Qu Wenruo --- fs/btrfs/extent_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 9afdcf0c70dd..2d228cc8b401 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -745,7 +745,7 @@ static void end_bio_extent_readpage(struct btrfs_bio *bbio) /* Update page status and unlock. */ end_page_read(page, uptodate, start, len); endio_readpage_release_extent(&processed, BTRFS_I(inode), - start, end, PageUptodate(page)); + start, end, uptodate); ASSERT(bio_offset + len > bio_offset); bio_offset += len; From patchwork Tue May 30 01:18:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 13259066 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E781C7EE2F for ; Tue, 30 May 2023 01:18:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229695AbjE3BSc (ORCPT ); Mon, 29 May 2023 21:18:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229775AbjE3BS3 (ORCPT ); Mon, 29 May 2023 21:18:29 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82927E0 for ; Mon, 29 May 2023 18:18:27 -0700 (PDT) Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 4221021A7B for ; Tue, 30 May 2023 01:18:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1685409506; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=M64yCdIpYm9evIREmBfoS+1aw+NVS5MRbE72A/RGzIA=; b=feXMLDUuOV9ak1fodA3C6QbFPBEjTZQ7Qu1jziHZKA9zdJOt9/SWDal6VyYMEk+42/CzHA Tp/iZv0hxBkiZXHN4VgDeMpdXAkkyK+txZncc41Y6vyLk0d0dpXJj4q5OABadBA0XJEwpd /nOYIi6kvAmi89ALxNcZiObdbdhhASI= Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap1.suse-dmz.suse.de (Postfix) with ESMTPS id B04361341B for ; Tue, 30 May 2023 01:18:25 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap1.suse-dmz.suse.de with ESMTPSA id 8Fh4IOFOdWRIIQAAGKfGzw (envelope-from ) for ; Tue, 30 May 2023 01:18:25 +0000 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH 3/3] btrfs: remove processed_extent infrastructure Date: Tue, 30 May 2023 09:18:05 +0800 Message-Id: X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org The structure processed_extent and the helper endio_readpage_release_extent() are used to reduce the number of calls of unlock_extent() during end_bio_extent_readpage() This is done by merging the range and only call the function either the status (uptodate or not) changes or the range is no longer continuous. However the behavior has been changed: - The range is always continuous Since it's the endio function of a btrfs bio, it's ensured the range is always continuous inside the same file. - The uptodate status is now per-bio (aka, will not change) Since commit 7609afac6775 ("btrfs: handle checksum validation and repair at the storage layer"), the function end_bio_extent_readpage() no longer handles the metadata/data verification. This means the @uptodate variable will not change during the function end_bio_extent_readpage() Thus there is no longer the need for processed_extent and the helper endio_readpage_release_extent(). Just call unlock_extent() at the end of end_bio_extent_readpage(). Signed-off-by: Qu Wenruo --- fs/btrfs/extent_io.c | 87 +++++--------------------------------------- 1 file changed, 9 insertions(+), 78 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 2d228cc8b401..6bf2dcf3ad28 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -581,75 +581,6 @@ static void end_bio_extent_writepage(struct btrfs_bio *bbio) bio_put(bio); } -/* - * Record previously processed extent range - * - * For endio_readpage_release_extent() to handle a full extent range, reducing - * the extent io operations. - */ -struct processed_extent { - struct btrfs_inode *inode; - /* Start of the range in @inode */ - u64 start; - /* End of the range in @inode */ - u64 end; - bool uptodate; -}; - -/* - * Try to release processed extent range - * - * May not release the extent range right now if the current range is - * contiguous to processed extent. - * - * Will release processed extent when any of @inode, @uptodate, the range is - * no longer contiguous to the processed range. - * - * Passing @inode == NULL will force processed extent to be released. - */ -static void endio_readpage_release_extent(struct processed_extent *processed, - struct btrfs_inode *inode, u64 start, u64 end, - bool uptodate) -{ - struct extent_state *cached = NULL; - struct extent_io_tree *tree; - - /* The first extent, initialize @processed */ - if (!processed->inode) - goto update; - - /* - * Contiguous to processed extent, just uptodate the end. - * - * Several things to notice: - * - * - bio can be merged as long as on-disk bytenr is contiguous - * This means we can have page belonging to other inodes, thus need to - * check if the inode still matches. - * - bvec can contain range beyond current page for multi-page bvec - * Thus we need to do processed->end + 1 >= start check - */ - if (processed->inode == inode && processed->uptodate == uptodate && - processed->end + 1 >= start && end >= processed->end) { - processed->end = end; - return; - } - - tree = &processed->inode->io_tree; - /* - * Now we don't have range contiguous to the processed range, release - * the processed range now. - */ - unlock_extent(tree, processed->start, processed->end, &cached); - -update: - /* Update processed to current range */ - processed->inode = inode; - processed->start = start; - processed->end = end; - processed->uptodate = uptodate; -} - static void begin_page_read(struct btrfs_fs_info *fs_info, struct page *page) { ASSERT(PageLocked(page)); @@ -674,20 +605,21 @@ static void begin_page_read(struct btrfs_fs_info *fs_info, struct page *page) static void end_bio_extent_readpage(struct btrfs_bio *bbio) { struct bio *bio = &bbio->bio; + struct inode *inode = bio_first_page_all(bio)->mapping->host; struct bio_vec *bvec; - struct processed_extent processed = { 0 }; + struct bvec_iter_all iter_all; + bool uptodate = !bio->bi_status; + u64 file_offset = page_offset(bio_first_page_all(bio)) + + bio_first_bvec_all(bio)->bv_offset; /* * The offset to the beginning of a bio, since one bio can never be * larger than UINT_MAX, u32 here is enough. */ u32 bio_offset = 0; - struct bvec_iter_all iter_all; ASSERT(!bio_flagged(bio, BIO_CLONED)); bio_for_each_segment_all(bvec, bio, iter_all) { - bool uptodate = !bio->bi_status; struct page *page = bvec->bv_page; - struct inode *inode = page->mapping->host; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); const u32 sectorsize = fs_info->sectorsize; u64 start; @@ -742,17 +674,16 @@ static void end_bio_extent_readpage(struct btrfs_bio *bbio) } } - /* Update page status and unlock. */ + /* Update page status. */ end_page_read(page, uptodate, start, len); - endio_readpage_release_extent(&processed, BTRFS_I(inode), - start, end, uptodate); ASSERT(bio_offset + len > bio_offset); bio_offset += len; } - /* Release the last extent */ - endio_readpage_release_extent(&processed, NULL, 0, 0, false); + /* Unlock the extent io tree. */ + unlock_extent(&BTRFS_I(inode)->io_tree, file_offset, + file_offset + bio_offset, NULL); bio_put(bio); }