Skip to content

Commit f1d97e7

Browse files
fdmananakdave
authored andcommitted
btrfs: add a global per cpu counter to track number of used extent maps
Add a per cpu counter that tracks the total number of extent maps that are in extent trees of inodes that belong to fs trees. This is going to be used in an upcoming change that adds a shrinker for extent maps. Only extent maps for fs trees are considered, because for special trees such as the data relocation tree we don't want to evict their extent maps which are critical for the relocation to work, and since those are limited, it's not a concern to have them in memory during the relocation of a block group. Another case are extent maps for free space cache inodes, which must always remain in memory, but those are limited (there's only one per free space cache inode, which means one per block group). Reviewed-by: Josef Bacik <[email protected]> Signed-off-by: Filipe Manana <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 5fa8a6b commit f1d97e7

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

fs/btrfs/disk-io.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,9 +1266,14 @@ static void free_global_roots(struct btrfs_fs_info *fs_info)
12661266

12671267
void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
12681268
{
1269+
struct percpu_counter *em_counter = &fs_info->evictable_extent_maps;
1270+
12691271
percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
12701272
percpu_counter_destroy(&fs_info->delalloc_bytes);
12711273
percpu_counter_destroy(&fs_info->ordered_bytes);
1274+
if (percpu_counter_initialized(em_counter))
1275+
ASSERT(percpu_counter_sum_positive(em_counter) == 0);
1276+
percpu_counter_destroy(em_counter);
12721277
percpu_counter_destroy(&fs_info->dev_replace.bio_counter);
12731278
btrfs_free_csum_hash(fs_info);
12741279
btrfs_free_stripe_hash_table(fs_info);
@@ -2848,6 +2853,10 @@ static int init_mount_fs_info(struct btrfs_fs_info *fs_info, struct super_block
28482853
if (ret)
28492854
return ret;
28502855

2856+
ret = percpu_counter_init(&fs_info->evictable_extent_maps, 0, GFP_KERNEL);
2857+
if (ret)
2858+
return ret;
2859+
28512860
ret = percpu_counter_init(&fs_info->dirty_metadata_bytes, 0, GFP_KERNEL);
28522861
if (ret)
28532862
return ret;

fs/btrfs/extent_map.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ static u64 range_end(u64 start, u64 len)
7676
return start + len;
7777
}
7878

79+
static void dec_evictable_extent_maps(struct btrfs_inode *inode)
80+
{
81+
struct btrfs_fs_info *fs_info = inode->root->fs_info;
82+
83+
if (!btrfs_is_testing(fs_info) && is_fstree(btrfs_root_id(inode->root)))
84+
percpu_counter_dec(&fs_info->evictable_extent_maps);
85+
}
86+
7987
static int tree_insert(struct rb_root_cached *root, struct extent_map *em)
8088
{
8189
struct rb_node **p = &root->rb_root.rb_node;
@@ -259,6 +267,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
259267
rb_erase_cached(&merge->rb_node, &tree->map);
260268
RB_CLEAR_NODE(&merge->rb_node);
261269
free_extent_map(merge);
270+
dec_evictable_extent_maps(inode);
262271
}
263272
}
264273

@@ -273,6 +282,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
273282
em->generation = max(em->generation, merge->generation);
274283
em->flags |= EXTENT_FLAG_MERGED;
275284
free_extent_map(merge);
285+
dec_evictable_extent_maps(inode);
276286
}
277287
}
278288

@@ -372,6 +382,8 @@ static int add_extent_mapping(struct btrfs_inode *inode,
372382
struct extent_map *em, int modified)
373383
{
374384
struct extent_map_tree *tree = &inode->extent_tree;
385+
struct btrfs_root *root = inode->root;
386+
struct btrfs_fs_info *fs_info = root->fs_info;
375387
int ret;
376388

377389
lockdep_assert_held_write(&tree->lock);
@@ -382,6 +394,9 @@ static int add_extent_mapping(struct btrfs_inode *inode,
382394

383395
setup_extent_mapping(inode, em, modified);
384396

397+
if (!btrfs_is_testing(fs_info) && is_fstree(btrfs_root_id(root)))
398+
percpu_counter_inc(&fs_info->evictable_extent_maps);
399+
385400
return 0;
386401
}
387402

@@ -467,6 +482,8 @@ void remove_extent_mapping(struct btrfs_inode *inode, struct extent_map *em)
467482
if (!(em->flags & EXTENT_FLAG_LOGGING))
468483
list_del_init(&em->list);
469484
RB_CLEAR_NODE(&em->rb_node);
485+
486+
dec_evictable_extent_maps(inode);
470487
}
471488

472489
static void replace_extent_mapping(struct btrfs_inode *inode,

fs/btrfs/fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,8 @@ struct btrfs_fs_info {
630630
s32 dirty_metadata_batch;
631631
s32 delalloc_batch;
632632

633+
struct percpu_counter evictable_extent_maps;
634+
633635
/* Protected by 'trans_lock'. */
634636
struct list_head dirty_cowonly_roots;
635637

0 commit comments

Comments
 (0)