Commit 854c2f36 authored by Boris Burkov's avatar Boris Burkov Committed by David Sterba
Browse files

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: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: default avatarBoris Burkov <boris@bur.io>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent cfc2de0f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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 @@ static noinline int find_free_extent(struct btrfs_root *root,
			    &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 @@ static noinline int find_free_extent(struct btrfs_root *root,
		}

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;
+3 −0
Original line number Diff line number Diff line
@@ -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 {
+78 −3
Original line number Diff line number Diff line
@@ -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,