Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

btrfs: extent-tree: Add trace events for space info numbers update

Add trace event for update_bytes_pinned() and update_bytes_may_use() to
detect underflow better.

The output would be something like (only showing data part):

## Buffered write start, 16K total ##
2255.954 xfs_io/860 btrfs:update_bytes_may_use:(nil)U: type=DATA old=0 diff=4096
2257.169 sudo/860 btrfs:update_bytes_may_use:(nil)U: type=DATA old=4096 diff=4096
2257.346 sudo/860 btrfs:update_bytes_may_use:(nil)U: type=DATA old=8192 diff=4096
2257.542 sudo/860 btrfs:update_bytes_may_use:(nil)U: type=DATA old=12288 diff=4096

## Delalloc start ##
3727.853 kworker/u8:3-e/700 btrfs:update_bytes_may_use:(nil)U: type=DATA old=16384 diff=-16384

## Space cache update ##
3733.132 sudo/862 btrfs:update_bytes_may_use:(nil)U: type=DATA old=0 diff=65536
3733.169 sudo/862 btrfs:update_bytes_may_use:(nil)U: type=DATA old=65536 diff=-65536
3739.868 sudo/862 btrfs:update_bytes_may_use:(nil)U: type=DATA old=0 diff=65536
3739.891 sudo/862 btrfs:update_bytes_may_use:(nil)U: type=DATA old=65536 diff=-65536

These two trace events will allow bcc tool to probe btrfs_space_info
changes and detect underflow with more details (e.g. backtrace for each
update).

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>

authored by

Qu Wenruo and committed by
David Sterba
480b9b4d 0185f364

+60 -16
+20 -16
fs/btrfs/extent-tree.c
··· 55 55 * Declare a helper function to detect underflow of various space info members 56 56 */ 57 57 #define DECLARE_SPACE_INFO_UPDATE(name) \ 58 - static inline void update_##name(struct btrfs_space_info *sinfo, \ 58 + static inline void update_##name(struct btrfs_fs_info *fs_info, \ 59 + struct btrfs_space_info *sinfo, \ 59 60 s64 bytes) \ 60 61 { \ 61 62 lockdep_assert_held(&sinfo->lock); \ 63 + trace_update_##name(fs_info, sinfo, sinfo->name, bytes); \ 62 64 if (bytes < 0 && sinfo->name < -bytes) { \ 63 65 WARN_ON(1); \ 64 66 sinfo->name = 0; \ ··· 4211 4209 data_sinfo->flags, bytes, 1); 4212 4210 return -ENOSPC; 4213 4211 } 4214 - update_bytes_may_use(data_sinfo, bytes); 4212 + update_bytes_may_use(fs_info, data_sinfo, bytes); 4215 4213 trace_btrfs_space_reservation(fs_info, "space_info", 4216 4214 data_sinfo->flags, bytes, 1); 4217 4215 spin_unlock(&data_sinfo->lock); ··· 4264 4262 4265 4263 data_sinfo = fs_info->data_sinfo; 4266 4264 spin_lock(&data_sinfo->lock); 4267 - update_bytes_may_use(data_sinfo, -len); 4265 + update_bytes_may_use(fs_info, data_sinfo, -len); 4268 4266 trace_btrfs_space_reservation(fs_info, "space_info", 4269 4267 data_sinfo->flags, len, 0); 4270 4268 spin_unlock(&data_sinfo->lock); ··· 5171 5169 * If not things get more complicated. 5172 5170 */ 5173 5171 if (used + orig_bytes <= space_info->total_bytes) { 5174 - update_bytes_may_use(space_info, orig_bytes); 5172 + update_bytes_may_use(fs_info, space_info, orig_bytes); 5175 5173 trace_btrfs_space_reservation(fs_info, "space_info", 5176 5174 space_info->flags, orig_bytes, 1); 5177 5175 ret = 0; 5178 5176 } else if (can_overcommit(fs_info, space_info, orig_bytes, flush, 5179 5177 system_chunk)) { 5180 - update_bytes_may_use(space_info, orig_bytes); 5178 + update_bytes_may_use(fs_info, space_info, orig_bytes); 5181 5179 trace_btrfs_space_reservation(fs_info, "space_info", 5182 5180 space_info->flags, orig_bytes, 1); 5183 5181 ret = 0; ··· 5505 5503 flush = BTRFS_RESERVE_FLUSH_ALL; 5506 5504 goto again; 5507 5505 } 5508 - update_bytes_may_use(space_info, -num_bytes); 5506 + update_bytes_may_use(fs_info, space_info, -num_bytes); 5509 5507 trace_btrfs_space_reservation(fs_info, "space_info", 5510 5508 space_info->flags, num_bytes, 0); 5511 5509 spin_unlock(&space_info->lock); ··· 5533 5531 ticket->bytes, 1); 5534 5532 list_del_init(&ticket->list); 5535 5533 num_bytes -= ticket->bytes; 5536 - update_bytes_may_use(space_info, ticket->bytes); 5534 + update_bytes_may_use(fs_info, space_info, 5535 + ticket->bytes); 5537 5536 ticket->bytes = 0; 5538 5537 space_info->tickets_id++; 5539 5538 wake_up(&ticket->wait); ··· 5542 5539 trace_btrfs_space_reservation(fs_info, "space_info", 5543 5540 space_info->flags, 5544 5541 num_bytes, 1); 5545 - update_bytes_may_use(space_info, num_bytes); 5542 + update_bytes_may_use(fs_info, space_info, num_bytes); 5546 5543 ticket->bytes -= num_bytes; 5547 5544 num_bytes = 0; 5548 5545 } ··· 5835 5832 num_bytes = min(num_bytes, 5836 5833 block_rsv->size - block_rsv->reserved); 5837 5834 block_rsv->reserved += num_bytes; 5838 - update_bytes_may_use(sinfo, num_bytes); 5835 + update_bytes_may_use(fs_info, sinfo, num_bytes); 5839 5836 trace_btrfs_space_reservation(fs_info, "space_info", 5840 5837 sinfo->flags, num_bytes, 5841 5838 1); 5842 5839 } 5843 5840 } else if (block_rsv->reserved > block_rsv->size) { 5844 5841 num_bytes = block_rsv->reserved - block_rsv->size; 5845 - update_bytes_may_use(sinfo, -num_bytes); 5842 + update_bytes_may_use(fs_info, sinfo, -num_bytes); 5846 5843 trace_btrfs_space_reservation(fs_info, "space_info", 5847 5844 sinfo->flags, num_bytes, 0); 5848 5845 block_rsv->reserved = block_rsv->size; ··· 6305 6302 old_val -= num_bytes; 6306 6303 btrfs_set_block_group_used(&cache->item, old_val); 6307 6304 cache->pinned += num_bytes; 6308 - update_bytes_pinned(cache->space_info, num_bytes); 6305 + update_bytes_pinned(info, cache->space_info, num_bytes); 6309 6306 cache->space_info->bytes_used -= num_bytes; 6310 6307 cache->space_info->disk_used -= num_bytes * factor; 6311 6308 spin_unlock(&cache->lock); ··· 6380 6377 spin_lock(&cache->space_info->lock); 6381 6378 spin_lock(&cache->lock); 6382 6379 cache->pinned += num_bytes; 6383 - update_bytes_pinned(cache->space_info, num_bytes); 6380 + update_bytes_pinned(fs_info, cache->space_info, num_bytes); 6384 6381 if (reserved) { 6385 6382 cache->reserved -= num_bytes; 6386 6383 cache->space_info->bytes_reserved -= num_bytes; ··· 6589 6586 } else { 6590 6587 cache->reserved += num_bytes; 6591 6588 space_info->bytes_reserved += num_bytes; 6592 - update_bytes_may_use(space_info, -ram_bytes); 6589 + update_bytes_may_use(cache->fs_info, space_info, -ram_bytes); 6593 6590 if (delalloc) 6594 6591 cache->delalloc_bytes += num_bytes; 6595 6592 } ··· 6745 6742 spin_lock(&space_info->lock); 6746 6743 spin_lock(&cache->lock); 6747 6744 cache->pinned -= len; 6748 - update_bytes_pinned(space_info, -len); 6745 + update_bytes_pinned(fs_info, space_info, -len); 6749 6746 6750 6747 trace_btrfs_space_reservation(fs_info, "pinned", 6751 6748 space_info->flags, len, 0); ··· 6766 6763 to_add = min(len, global_rsv->size - 6767 6764 global_rsv->reserved); 6768 6765 global_rsv->reserved += to_add; 6769 - update_bytes_may_use(space_info, to_add); 6766 + update_bytes_may_use(fs_info, space_info, 6767 + to_add); 6770 6768 if (global_rsv->reserved >= global_rsv->size) 6771 6769 global_rsv->full = 1; 6772 6770 trace_btrfs_space_reservation(fs_info, ··· 11028 11024 spin_lock(&space_info->lock); 11029 11025 spin_lock(&block_group->lock); 11030 11026 11031 - update_bytes_pinned(space_info, -block_group->pinned); 11027 + update_bytes_pinned(fs_info, space_info, -block_group->pinned); 11032 11028 space_info->bytes_readonly += block_group->pinned; 11033 11029 percpu_counter_add_batch(&space_info->total_bytes_pinned, 11034 11030 -block_group->pinned,
+40
include/trace/events/btrfs.h
··· 29 29 struct btrfs_qgroup; 30 30 struct extent_io_tree; 31 31 struct prelim_ref; 32 + struct btrfs_space_info; 32 33 33 34 TRACE_DEFINE_ENUM(FLUSH_DELAYED_ITEMS_NR); 34 35 TRACE_DEFINE_ENUM(FLUSH_DELAYED_ITEMS); ··· 2091 2090 DEFINE_BTRFS_LOCK_EVENT(btrfs_try_tree_read_lock); 2092 2091 DEFINE_BTRFS_LOCK_EVENT(btrfs_try_tree_write_lock); 2093 2092 DEFINE_BTRFS_LOCK_EVENT(btrfs_tree_read_lock_atomic); 2093 + 2094 + DECLARE_EVENT_CLASS(btrfs__space_info_update, 2095 + 2096 + TP_PROTO(struct btrfs_fs_info *fs_info, 2097 + struct btrfs_space_info *sinfo, u64 old, s64 diff), 2098 + 2099 + TP_ARGS(fs_info, sinfo, old, diff), 2100 + 2101 + TP_STRUCT__entry_btrfs( 2102 + __field( u64, type ) 2103 + __field( u64, old ) 2104 + __field( s64, diff ) 2105 + ), 2106 + 2107 + TP_fast_assign_btrfs(fs_info, 2108 + __entry->type = sinfo->flags; 2109 + __entry->old = old; 2110 + __entry->diff = diff; 2111 + ), 2112 + TP_printk_btrfs("type=%s old=%llu diff=%lld", 2113 + __print_flags(__entry->type, "|", BTRFS_GROUP_FLAGS), 2114 + __entry->old, __entry->diff) 2115 + ); 2116 + 2117 + DEFINE_EVENT(btrfs__space_info_update, update_bytes_may_use, 2118 + 2119 + TP_PROTO(struct btrfs_fs_info *fs_info, 2120 + struct btrfs_space_info *sinfo, u64 old, s64 diff), 2121 + 2122 + TP_ARGS(fs_info, sinfo, old, diff) 2123 + ); 2124 + 2125 + DEFINE_EVENT(btrfs__space_info_update, update_bytes_pinned, 2126 + 2127 + TP_PROTO(struct btrfs_fs_info *fs_info, 2128 + struct btrfs_space_info *sinfo, u64 old, s64 diff), 2129 + 2130 + TP_ARGS(fs_info, sinfo, old, diff) 2131 + ); 2094 2132 2095 2133 #endif /* _TRACE_BTRFS_H */ 2096 2134