Skip to content

Commit cc970d2

Browse files
loemrawkdave
authored andcommitted
btrfs: add tracepoint for search slot restart tracking
Add a btrfs_search_slot_restart tracepoint that fires at each restart site in btrfs_search_slot(), recording the root, tree level, and reason for the restart. This enables tracking search slot restarts which contribute to COW amplification under memory pressure. The four restart reasons are: - write_lock: insufficient write lock level, need to restart with higher lock - setup_nodes: node setup returned -EAGAIN - slot_zero: insertion at slot 0 requires higher write lock level - read_block: read_block_for_search returned -EAGAIN (block not cached or lock contention) COW counts are already tracked by the existing trace_btrfs_cow_block() tracepoint. The per-restart-site tracepoint avoids counter overhead in the critical path when tracepoints are disabled, and provides richer per-event information that bpftrace scripts can aggregate into counts, histograms, and per-root breakdowns. Reviewed-by: Filipe Manana <[email protected]> Reviewed-by: Boris Burkov <[email protected]> Signed-off-by: Leo Martins <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent f9a4854 commit cc970d2

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

fs/btrfs/ctree.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
21022102
p->nodes[level + 1])) {
21032103
write_lock_level = level + 1;
21042104
btrfs_release_path(p);
2105+
trace_btrfs_search_slot_restart(root, level, "write_lock");
21052106
goto again;
21062107
}
21072108

@@ -2164,8 +2165,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
21642165
p->slots[level] = slot;
21652166
ret2 = setup_nodes_for_search(trans, root, p, b, level, ins_len,
21662167
&write_lock_level);
2167-
if (ret2 == -EAGAIN)
2168+
if (ret2 == -EAGAIN) {
2169+
trace_btrfs_search_slot_restart(root, level, "setup_nodes");
21682170
goto again;
2171+
}
21692172
if (ret2) {
21702173
ret = ret2;
21712174
goto done;
@@ -2181,6 +2184,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
21812184
if (slot == 0 && ins_len && write_lock_level < level + 1) {
21822185
write_lock_level = level + 1;
21832186
btrfs_release_path(p);
2187+
trace_btrfs_search_slot_restart(root, level, "slot_zero");
21842188
goto again;
21852189
}
21862190

@@ -2194,8 +2198,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
21942198
}
21952199

21962200
ret2 = read_block_for_search(root, p, &b, slot, key);
2197-
if (ret2 == -EAGAIN && !p->nowait)
2201+
if (ret2 == -EAGAIN && !p->nowait) {
2202+
trace_btrfs_search_slot_restart(root, level, "read_block");
21982203
goto again;
2204+
}
21992205
if (ret2) {
22002206
ret = ret2;
22012207
goto done;

include/trace/events/btrfs.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,30 @@ TRACE_EVENT(btrfs_cow_block,
11131113
__entry->cow_level)
11141114
);
11151115

1116+
TRACE_EVENT(btrfs_search_slot_restart,
1117+
1118+
TP_PROTO(const struct btrfs_root *root, int level,
1119+
const char *reason),
1120+
1121+
TP_ARGS(root, level, reason),
1122+
1123+
TP_STRUCT__entry_btrfs(
1124+
__field( u64, root_objectid )
1125+
__field( int, level )
1126+
__string( reason, reason )
1127+
),
1128+
1129+
TP_fast_assign_btrfs(root->fs_info,
1130+
__entry->root_objectid = btrfs_root_id(root);
1131+
__entry->level = level;
1132+
__assign_str(reason);
1133+
),
1134+
1135+
TP_printk_btrfs("root=%llu(%s) level=%d reason=%s",
1136+
show_root_type(__entry->root_objectid),
1137+
__entry->level, __get_str(reason))
1138+
);
1139+
11161140
TRACE_EVENT(btrfs_space_reservation,
11171141

11181142
TP_PROTO(const struct btrfs_fs_info *fs_info, const char *type, u64 val,

0 commit comments

Comments
 (0)