diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 6df03ba36026..67b77f1d113e 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c @@ -158,6 +158,10 @@ void btrfs_clear_lock_blocking_write(struct extent_buffer *eb) */ void btrfs_tree_read_lock(struct extent_buffer *eb) { + u64 start_ns = 0; + + if (trace_btrfs_tree_read_lock_enabled()) + start_ns = ktime_get_ns(); again: BUG_ON(!atomic_read(&eb->blocking_writers) && current->pid == eb->lock_owner); @@ -174,6 +178,7 @@ again: BUG_ON(eb->lock_nested); eb->lock_nested = true; read_unlock(&eb->lock); + trace_btrfs_tree_read_lock(eb, start_ns); return; } if (atomic_read(&eb->blocking_writers)) { @@ -184,6 +189,7 @@ again: } btrfs_assert_tree_read_locks_get(eb); btrfs_assert_spinning_readers_get(eb); + trace_btrfs_tree_read_lock(eb, start_ns); } /* @@ -299,6 +305,11 @@ void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb) */ void btrfs_tree_lock(struct extent_buffer *eb) { + u64 start_ns = 0; + + if (trace_btrfs_tree_lock_enabled()) + start_ns = ktime_get_ns(); + WARN_ON(eb->lock_owner == current->pid); again: wait_event(eb->read_lock_wq, atomic_read(&eb->blocking_readers) == 0); @@ -312,6 +323,7 @@ again: btrfs_assert_spinning_writers_get(eb); btrfs_assert_tree_write_locks_get(eb); eb->lock_owner = current->pid; + trace_btrfs_tree_lock(eb, start_ns); } /* diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index 8b12753fee78..e27ed5afb958 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -2005,6 +2005,50 @@ TRACE_EVENT(btrfs_convert_extent_bit, __print_flags(__entry->clear_bits, "|", EXTENT_FLAGS)) ); +DECLARE_EVENT_CLASS(btrfs_sleep_tree_lock, + TP_PROTO(const struct extent_buffer *eb, u64 start_ns), + + TP_ARGS(eb, start_ns), + + TP_STRUCT__entry_btrfs( + __field( u64, block ) + __field( u64, generation ) + __field( u64, start_ns ) + __field( u64, end_ns ) + __field( u64, diff_ns ) + __field( u64, owner ) + __field( int, is_log_tree ) + ), + + TP_fast_assign_btrfs(eb->fs_info, + __entry->block = eb->start; + __entry->generation = btrfs_header_generation(eb); + __entry->start_ns = start_ns; + __entry->end_ns = ktime_get_ns(); + __entry->diff_ns = __entry->end_ns - start_ns; + __entry->owner = btrfs_header_owner(eb); + __entry->is_log_tree = (eb->log_index >= 0); + ), + + TP_printk_btrfs( +"block=%llu generation=%llu start_ns=%llu end_ns=%llu diff_ns=%llu owner=%llu is_log_tree=%d", + __entry->block, __entry->generation, + __entry->start_ns, __entry->end_ns, __entry->diff_ns, + __entry->owner, __entry->is_log_tree) +); + +DEFINE_EVENT(btrfs_sleep_tree_lock, btrfs_tree_read_lock, + TP_PROTO(const struct extent_buffer *eb, u64 start_ns), + + TP_ARGS(eb, start_ns) +); + +DEFINE_EVENT(btrfs_sleep_tree_lock, btrfs_tree_lock, + TP_PROTO(const struct extent_buffer *eb, u64 start_ns), + + TP_ARGS(eb, start_ns) +); + #endif /* _TRACE_BTRFS_H */ /* This part must be outside protection */