Skip to content

Commit 9e82d3e

Browse files
fdmananakdave
authored andcommitted
btrfs: use a regular rb_root instead of cached rb_root for extent_map_tree
We are currently using a cached rb_root (struct rb_root_cached) for the rb root of struct extent_map_tree. This doesn't offer much of an advantage here because: 1) It's only advantage over the regular rb_root is that it caches a pointer to the left most node (first node), so a call to rb_first_cached() doesn't have to chase pointers until it reaches the left most node; 2) We only have two scenarios that access left most node with rb_first_cached(): When dropping all extent maps from an inode, during inode eviction; When iterating over extent maps during the extent map shrinker; 3) In both cases we keep removing extent maps, which causes deletion of the left most node so rb_erase_cached() has to call rb_next() to find out what's the next left most node and assign it to struct rb_root_cached::rb_leftmost; 4) We can do that ourselves in those two uses cases and stop using a rb_root_cached rb tree and use instead a regular rb_root rb tree. This reduces the size of struct extent_map_tree by 8 bytes and, since this structure is embedded in struct btrfs_inode, it also reduces the size of that structure by 8 bytes. So on a 64 bits platform the size of btrfs_inode is reduced from 1032 bytes down to 1024 bytes. This means we will be able to have 4 inodes per 4K page instead of 3. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 6a2996c commit 9e82d3e

File tree

3 files changed

+30
-26
lines changed

3 files changed

+30
-26
lines changed

fs/btrfs/extent_map.c

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ void __cold extent_map_exit(void)
3333
*/
3434
void extent_map_tree_init(struct extent_map_tree *tree)
3535
{
36-
tree->root = RB_ROOT_CACHED;
36+
tree->root = RB_ROOT;
3737
INIT_LIST_HEAD(&tree->modified_extents);
3838
rwlock_init(&tree->lock);
3939
}
@@ -85,27 +85,24 @@ static void dec_evictable_extent_maps(struct btrfs_inode *inode)
8585
percpu_counter_dec(&fs_info->evictable_extent_maps);
8686
}
8787

88-
static int tree_insert(struct rb_root_cached *root, struct extent_map *em)
88+
static int tree_insert(struct rb_root *root, struct extent_map *em)
8989
{
90-
struct rb_node **p = &root->rb_root.rb_node;
90+
struct rb_node **p = &root->rb_node;
9191
struct rb_node *parent = NULL;
9292
struct extent_map *entry = NULL;
9393
struct rb_node *orig_parent = NULL;
9494
u64 end = range_end(em->start, em->len);
95-
bool leftmost = true;
9695

9796
while (*p) {
9897
parent = *p;
9998
entry = rb_entry(parent, struct extent_map, rb_node);
10099

101-
if (em->start < entry->start) {
100+
if (em->start < entry->start)
102101
p = &(*p)->rb_left;
103-
} else if (em->start >= extent_map_end(entry)) {
102+
else if (em->start >= extent_map_end(entry))
104103
p = &(*p)->rb_right;
105-
leftmost = false;
106-
} else {
104+
else
107105
return -EEXIST;
108-
}
109106
}
110107

111108
orig_parent = parent;
@@ -128,7 +125,7 @@ static int tree_insert(struct rb_root_cached *root, struct extent_map *em)
128125
return -EEXIST;
129126

130127
rb_link_node(&em->rb_node, orig_parent, p);
131-
rb_insert_color_cached(&em->rb_node, root, leftmost);
128+
rb_insert_color(&em->rb_node, root);
132129
return 0;
133130
}
134131

@@ -265,7 +262,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
265262
em->generation = max(em->generation, merge->generation);
266263
em->flags |= EXTENT_FLAG_MERGED;
267264

268-
rb_erase_cached(&merge->rb_node, &tree->root);
265+
rb_erase(&merge->rb_node, &tree->root);
269266
RB_CLEAR_NODE(&merge->rb_node);
270267
free_extent_map(merge);
271268
dec_evictable_extent_maps(inode);
@@ -278,7 +275,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
278275
if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) {
279276
em->len += merge->len;
280277
em->block_len += merge->block_len;
281-
rb_erase_cached(&merge->rb_node, &tree->root);
278+
rb_erase(&merge->rb_node, &tree->root);
282279
RB_CLEAR_NODE(&merge->rb_node);
283280
em->generation = max(em->generation, merge->generation);
284281
em->flags |= EXTENT_FLAG_MERGED;
@@ -410,7 +407,7 @@ __lookup_extent_mapping(struct extent_map_tree *tree,
410407
struct rb_node *prev_or_next = NULL;
411408
u64 end = range_end(start, len);
412409

413-
rb_node = __tree_search(&tree->root.rb_root, start, &prev_or_next);
410+
rb_node = __tree_search(&tree->root, start, &prev_or_next);
414411
if (!rb_node) {
415412
if (prev_or_next)
416413
rb_node = prev_or_next;
@@ -479,7 +476,7 @@ void remove_extent_mapping(struct btrfs_inode *inode, struct extent_map *em)
479476
lockdep_assert_held_write(&tree->lock);
480477

481478
WARN_ON(em->flags & EXTENT_FLAG_PINNED);
482-
rb_erase_cached(&em->rb_node, &tree->root);
479+
rb_erase(&em->rb_node, &tree->root);
483480
if (!(em->flags & EXTENT_FLAG_LOGGING))
484481
list_del_init(&em->list);
485482
RB_CLEAR_NODE(&em->rb_node);
@@ -500,7 +497,7 @@ static void replace_extent_mapping(struct btrfs_inode *inode,
500497
ASSERT(extent_map_in_tree(cur));
501498
if (!(cur->flags & EXTENT_FLAG_LOGGING))
502499
list_del_init(&cur->list);
503-
rb_replace_node_cached(&cur->rb_node, &new->rb_node, &tree->root);
500+
rb_replace_node(&cur->rb_node, &new->rb_node, &tree->root);
504501
RB_CLEAR_NODE(&cur->rb_node);
505502

506503
setup_extent_mapping(inode, new, modified);
@@ -657,18 +654,23 @@ int btrfs_add_extent_mapping(struct btrfs_inode *inode,
657654
static void drop_all_extent_maps_fast(struct btrfs_inode *inode)
658655
{
659656
struct extent_map_tree *tree = &inode->extent_tree;
657+
struct rb_node *node;
660658

661659
write_lock(&tree->lock);
662-
while (!RB_EMPTY_ROOT(&tree->root.rb_root)) {
660+
node = rb_first(&tree->root);
661+
while (node) {
663662
struct extent_map *em;
664-
struct rb_node *node;
663+
struct rb_node *next = rb_next(node);
665664

666-
node = rb_first_cached(&tree->root);
667665
em = rb_entry(node, struct extent_map, rb_node);
668666
em->flags &= ~(EXTENT_FLAG_PINNED | EXTENT_FLAG_LOGGING);
669667
remove_extent_mapping(inode, em);
670668
free_extent_map(em);
671-
cond_resched_rwlock_write(&tree->lock);
669+
670+
if (cond_resched_rwlock_write(&tree->lock))
671+
node = rb_first(&tree->root);
672+
else
673+
node = next;
672674
}
673675
write_unlock(&tree->lock);
674676
}
@@ -1058,12 +1060,12 @@ static long btrfs_scan_inode(struct btrfs_inode *inode, long *scanned, long nr_t
10581060
return 0;
10591061

10601062
write_lock(&tree->lock);
1061-
node = rb_first_cached(&tree->root);
1063+
node = rb_first(&tree->root);
10621064
while (node) {
1065+
struct rb_node *next = rb_next(node);
10631066
struct extent_map *em;
10641067

10651068
em = rb_entry(node, struct extent_map, rb_node);
1066-
node = rb_next(node);
10671069
(*scanned)++;
10681070

10691071
if (em->flags & EXTENT_FLAG_PINNED)
@@ -1094,7 +1096,9 @@ static long btrfs_scan_inode(struct btrfs_inode *inode, long *scanned, long nr_t
10941096
* lock and took it again.
10951097
*/
10961098
if (cond_resched_rwlock_write(&tree->lock))
1097-
node = rb_first_cached(&tree->root);
1099+
node = rb_first(&tree->root);
1100+
else
1101+
node = next;
10981102
}
10991103
write_unlock(&tree->lock);
11001104
up_read(&inode->i_mmap_lock);

fs/btrfs/extent_map.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ struct extent_map {
115115
};
116116

117117
struct extent_map_tree {
118-
struct rb_root_cached root;
118+
struct rb_root root;
119119
struct list_head modified_extents;
120120
rwlock_t lock;
121121
};

fs/btrfs/tests/extent-map-tests.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ static int free_extent_map_tree(struct btrfs_inode *inode)
1919
int ret = 0;
2020

2121
write_lock(&em_tree->lock);
22-
while (!RB_EMPTY_ROOT(&em_tree->root.rb_root)) {
23-
node = rb_first_cached(&em_tree->root);
22+
while (!RB_EMPTY_ROOT(&em_tree->root)) {
23+
node = rb_first(&em_tree->root);
2424
em = rb_entry(node, struct extent_map, rb_node);
2525
remove_extent_mapping(inode, em);
2626

@@ -551,7 +551,7 @@ static int validate_range(struct extent_map_tree *em_tree, int index)
551551
struct rb_node *n;
552552
int i;
553553

554-
for (i = 0, n = rb_first_cached(&em_tree->root);
554+
for (i = 0, n = rb_first(&em_tree->root);
555555
valid_ranges[index][i].len && n;
556556
i++, n = rb_next(n)) {
557557
struct extent_map *entry = rb_entry(n, struct extent_map, rb_node);

0 commit comments

Comments
 (0)