btrfs: add more find_free_extent tracepoints
find_free_extent is a complicated function. It consists (at least) of: - a hint that jumps into the middle of a for loop macro - a middle loop trying every raid level - an outer loop ascending through ffe loop levels - complicated logic for skipping some of those ffe loop levels - multiple underlying in-bg allocators (zoned, cluster, no cluster) Which is all to say that more tracing is helpful for debugging its behavior. Add two new tracepoints: at the entrance to the block_groups loop (hit for every raid level and every ffe_ctl loop) and at the point we seriously consider a block_group for allocation. This way we can see the whole path through the algorithm, including hints, multiple loops, etc. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Boris Burkov <boris@bur.io> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
cfc2de0fce
commit
854c2f365d
|
@ -4261,6 +4261,7 @@ static noinline int find_free_extent(struct btrfs_root *root,
|
|||
block_group->flags);
|
||||
btrfs_lock_block_group(block_group,
|
||||
ffe_ctl->delalloc);
|
||||
ffe_ctl->hinted = true;
|
||||
goto have_block_group;
|
||||
}
|
||||
} else if (block_group) {
|
||||
|
@ -4268,6 +4269,7 @@ static noinline int find_free_extent(struct btrfs_root *root,
|
|||
}
|
||||
}
|
||||
search:
|
||||
trace_find_free_extent_search_loop(root, ffe_ctl);
|
||||
ffe_ctl->have_caching_bg = false;
|
||||
if (ffe_ctl->index == btrfs_bg_flags_to_raid_index(ffe_ctl->flags) ||
|
||||
ffe_ctl->index == 0)
|
||||
|
@ -4277,6 +4279,7 @@ search:
|
|||
&space_info->block_groups[ffe_ctl->index], list) {
|
||||
struct btrfs_block_group *bg_ret;
|
||||
|
||||
ffe_ctl->hinted = false;
|
||||
/* If the block group is read-only, we can skip it entirely. */
|
||||
if (unlikely(block_group->ro)) {
|
||||
if (ffe_ctl->for_treelog)
|
||||
|
@ -4318,6 +4321,7 @@ search:
|
|||
}
|
||||
|
||||
have_block_group:
|
||||
trace_find_free_extent_have_block_group(root, ffe_ctl, block_group);
|
||||
ffe_ctl->cached = btrfs_block_group_done(block_group);
|
||||
if (unlikely(!ffe_ctl->cached)) {
|
||||
ffe_ctl->have_caching_bg = true;
|
||||
|
|
|
@ -76,6 +76,9 @@ struct find_free_extent_ctl {
|
|||
|
||||
/* Allocation policy */
|
||||
enum btrfs_extent_allocation_policy policy;
|
||||
|
||||
/* Whether or not the allocator is currently following a hint */
|
||||
bool hinted;
|
||||
};
|
||||
|
||||
enum btrfs_inline_ref_type {
|
||||
|
|
|
@ -1268,6 +1268,77 @@ TRACE_EVENT(find_free_extent,
|
|||
BTRFS_GROUP_FLAGS))
|
||||
);
|
||||
|
||||
TRACE_EVENT(find_free_extent_search_loop,
|
||||
|
||||
TP_PROTO(const struct btrfs_root *root,
|
||||
const struct find_free_extent_ctl *ffe_ctl),
|
||||
|
||||
TP_ARGS(root, ffe_ctl),
|
||||
|
||||
TP_STRUCT__entry_btrfs(
|
||||
__field( u64, root_objectid )
|
||||
__field( u64, num_bytes )
|
||||
__field( u64, empty_size )
|
||||
__field( u64, flags )
|
||||
__field( u64, loop )
|
||||
),
|
||||
|
||||
TP_fast_assign_btrfs(root->fs_info,
|
||||
__entry->root_objectid = root->root_key.objectid;
|
||||
__entry->num_bytes = ffe_ctl->num_bytes;
|
||||
__entry->empty_size = ffe_ctl->empty_size;
|
||||
__entry->flags = ffe_ctl->flags;
|
||||
__entry->loop = ffe_ctl->loop;
|
||||
),
|
||||
|
||||
TP_printk_btrfs("root=%llu(%s) len=%llu empty_size=%llu flags=%llu(%s) loop=%llu",
|
||||
show_root_type(__entry->root_objectid),
|
||||
__entry->num_bytes, __entry->empty_size, __entry->flags,
|
||||
__print_flags((unsigned long)__entry->flags, "|", BTRFS_GROUP_FLAGS),
|
||||
__entry->loop)
|
||||
);
|
||||
|
||||
TRACE_EVENT(find_free_extent_have_block_group,
|
||||
|
||||
TP_PROTO(const struct btrfs_root *root,
|
||||
const struct find_free_extent_ctl *ffe_ctl,
|
||||
const struct btrfs_block_group *block_group),
|
||||
|
||||
TP_ARGS(root, ffe_ctl, block_group),
|
||||
|
||||
TP_STRUCT__entry_btrfs(
|
||||
__field( u64, root_objectid )
|
||||
__field( u64, num_bytes )
|
||||
__field( u64, empty_size )
|
||||
__field( u64, flags )
|
||||
__field( u64, loop )
|
||||
__field( bool, hinted )
|
||||
__field( u64, bg_start )
|
||||
__field( u64, bg_flags )
|
||||
),
|
||||
|
||||
TP_fast_assign_btrfs(root->fs_info,
|
||||
__entry->root_objectid = root->root_key.objectid;
|
||||
__entry->num_bytes = ffe_ctl->num_bytes;
|
||||
__entry->empty_size = ffe_ctl->empty_size;
|
||||
__entry->flags = ffe_ctl->flags;
|
||||
__entry->loop = ffe_ctl->loop;
|
||||
__entry->hinted = ffe_ctl->hinted;
|
||||
__entry->bg_start = block_group->start;
|
||||
__entry->bg_flags = block_group->flags;
|
||||
),
|
||||
|
||||
TP_printk_btrfs(
|
||||
"root=%llu(%s) len=%llu empty_size=%llu flags=%llu(%s) loop=%llu hinted=%d block_group=%llu bg_flags=%llu(%s)",
|
||||
show_root_type(__entry->root_objectid),
|
||||
__entry->num_bytes, __entry->empty_size, __entry->flags,
|
||||
__print_flags((unsigned long)__entry->flags, "|", BTRFS_GROUP_FLAGS),
|
||||
__entry->loop, __entry->hinted,
|
||||
__entry->bg_start, __entry->bg_flags,
|
||||
__print_flags((unsigned long)__entry->bg_flags, "|",
|
||||
BTRFS_GROUP_FLAGS))
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(btrfs__reserve_extent,
|
||||
|
||||
TP_PROTO(const struct btrfs_block_group *block_group,
|
||||
|
@ -1280,6 +1351,8 @@ DECLARE_EVENT_CLASS(btrfs__reserve_extent,
|
|||
__field( u64, flags )
|
||||
__field( u64, start )
|
||||
__field( u64, len )
|
||||
__field( u64, loop )
|
||||
__field( bool, hinted )
|
||||
),
|
||||
|
||||
TP_fast_assign_btrfs(block_group->fs_info,
|
||||
|
@ -1287,15 +1360,17 @@ DECLARE_EVENT_CLASS(btrfs__reserve_extent,
|
|||
__entry->flags = block_group->flags;
|
||||
__entry->start = ffe_ctl->search_start;
|
||||
__entry->len = ffe_ctl->num_bytes;
|
||||
__entry->loop = ffe_ctl->loop;
|
||||
__entry->hinted = ffe_ctl->hinted;
|
||||
),
|
||||
|
||||
TP_printk_btrfs("root=%llu(%s) block_group=%llu flags=%llu(%s) "
|
||||
"start=%llu len=%llu",
|
||||
TP_printk_btrfs(
|
||||
"root=%llu(%s) block_group=%llu flags=%llu(%s) start=%llu len=%llu loop=%llu hinted=%d",
|
||||
show_root_type(BTRFS_EXTENT_TREE_OBJECTID),
|
||||
__entry->bg_objectid,
|
||||
__entry->flags, __print_flags((unsigned long)__entry->flags,
|
||||
"|", BTRFS_GROUP_FLAGS),
|
||||
__entry->start, __entry->len)
|
||||
__entry->start, __entry->len, __entry->loop, __entry->hinted)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(btrfs__reserve_extent, btrfs_reserve_extent,
|
||||
|
|
Loading…
Reference in New Issue