All of lore.kernel.org
 help / color / mirror / Atom feed
From: robbieko <robbieko@synology.com>
To: linux-btrfs@vger.kernel.org
Cc: Robbie Ko <robbieko@synology.com>
Subject: [PATCH v2] btrfs: speedup mount time with readahead chunk tree
Date: Tue,  7 Jul 2020 11:59:44 +0800	[thread overview]
Message-ID: <20200707035944.15150-1-robbieko@synology.com> (raw)

From: Robbie Ko <robbieko@synology.com>

When mounting, we always need to read the whole chunk tree,
when there are too many chunk items, most of the time is
spent on btrfs_read_chunk_tree, because we only read one
leaf at a time.

It is unreasonable to limit the readahead mechanism to a
range of 64k, so we have removed that limit.

In addition we added reada_maximum_size to customize the
size of the pre-reader, The default is 64k to maintain the
original behavior.

So we fix this by used readahead mechanism, and set readahead
max size to ULLONG_MAX which reads all the leaves after the
key in the node when reading a level 1 node.

I have a test environment as follows:

200TB btrfs volume: used 192TB

Data, single: total=192.00TiB, used=192.00TiB
System, DUP: total=40.00MiB, used=19.91MiB
Metadata, DUP: total=63.00GiB, used=46.46GiB
GlobalReserve, single: total=2.00GiB, used=0.00B

chunk tree level : 2
chunk tree tree:
   nodes: 4
   leaves: 1270
   total: 1274
chunk tree size: 19.9 MB
SYSTEM chunks count : 2 (8MB, 32MB)

btrfs_read_chunk_tree spends the following time:
before: 1.89s
patch: 0.27s
Speed increase of about 85%.

Signed-off-by: Robbie Ko <robbieko@synology.com>
---
Changelog:
v2:
- add performance testing
- remove readahead logical bytenr 64k limit
- add reada_maximum_size for customize
---
 fs/btrfs/ctree.c   | 23 +++++++++++------------
 fs/btrfs/ctree.h   |  1 +
 fs/btrfs/volumes.c |  2 ++
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 3a7648bff42c..dc84f526cd93 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -75,7 +75,14 @@ size_t __const btrfs_get_num_csums(void)
 
 struct btrfs_path *btrfs_alloc_path(void)
 {
-	return kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
+	struct btrfs_path *path;
+
+	path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
+
+	if (path)
+		path->reada_maximum_size = 65536;
+
+	return path;
 }
 
 /* this also releases the path */
@@ -2161,12 +2168,10 @@ static void reada_for_search(struct btrfs_fs_info *fs_info,
 	struct btrfs_disk_key disk_key;
 	u32 nritems;
 	u64 search;
-	u64 target;
 	u64 nread = 0;
 	struct extent_buffer *eb;
 	u32 nr;
 	u32 blocksize;
-	u32 nscan = 0;
 
 	if (level != 1)
 		return;
@@ -2184,8 +2189,6 @@ static void reada_for_search(struct btrfs_fs_info *fs_info,
 		return;
 	}
 
-	target = search;
-
 	nritems = btrfs_header_nritems(node);
 	nr = slot;
 
@@ -2205,13 +2208,9 @@ static void reada_for_search(struct btrfs_fs_info *fs_info,
 				break;
 		}
 		search = btrfs_node_blockptr(node, nr);
-		if ((search <= target && target - search <= 65536) ||
-		    (search > target && search - target <= 65536)) {
-			readahead_tree_block(fs_info, search);
-			nread += blocksize;
-		}
-		nscan++;
-		if ((nread > 65536 || nscan > 32))
+		readahead_tree_block(fs_info, search);
+		nread += blocksize;
+		if (nread > path->reada_maximum_size)
 			break;
 	}
 }
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index d404cce8ae40..ea88a6473eb8 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -360,6 +360,7 @@ struct btrfs_path {
 	/* if there is real range locking, this locks field will change */
 	u8 locks[BTRFS_MAX_LEVEL];
 	u8 reada;
+	u64 reada_maximum_size;
 	/* keep some upper locks as we walk down */
 	u8 lowest_level;
 
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 0d6e785bcb98..fc87b2e9e865 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7043,6 +7043,8 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
 	path = btrfs_alloc_path();
 	if (!path)
 		return -ENOMEM;
+	path->reada = READA_FORWARD;
+	path->reada_maximum_size = ULLONG_MAX;
 
 	/*
 	 * uuid_mutex is needed only if we are mounting a sprout FS
-- 
2.17.1


             reply	other threads:[~2020-07-07  3:59 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-07  3:59 robbieko [this message]
2020-07-07 19:25 ` [PATCH v2] btrfs: speedup mount time with readahead chunk tree David Sterba
2020-07-08  2:19   ` Robbie Ko
2020-07-08 14:04     ` David Sterba
2020-07-08 14:57       ` Holger Hoffstätte
2020-07-08 15:21         ` David Sterba
2020-07-09  1:46         ` Robbie Ko
2020-07-09  7:17           ` Holger Hoffstätte
2020-07-08 21:11   ` David Sterba
2020-07-09  2:38     ` Robbie Ko
2020-07-09  9:13       ` David Sterba
2020-07-10  1:54         ` Robbie Ko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200707035944.15150-1-robbieko@synology.com \
    --to=robbieko@synology.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.