From: Josef Bacik <josef@toxicpanda.com>
Date: Fri, 9 Oct 2020 09:28:19 -0400
Subject: btrfs: add a trace point for reserve tickets
Git-commit: ac1ea10e757a57fb61512ae9beb2ef67e5340e31
Patch-mainline: v5.12-rc1
References: bsc#1202528
While debugging a ENOSPC related performance problem I needed to see the
time difference between start and end of a reserve ticket, so add a
trace point to report when we handle a reserve ticket.
I opted to spit out start_ns itself without calculating the difference
because there could be a gap between enabling the tracepoint and setting
start_ns. Doing it this way allows us to filter on 0 start_ns so we
don't get bogus entries, and we can easily calculate the time difference
with bpftrace or something else.
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Acked-by: Nikolay Borisov <nborisov@suse.com>
---
fs/btrfs/space-info.c | 10 +++++++++-
include/trace/events/btrfs.h | 30 ++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+), 1 deletion(-)
--- a/fs/btrfs/space-info.c
+++ b/fs/btrfs/space-info.c
@@ -1115,6 +1115,7 @@ static void wait_reserve_ticket(struct b
static int handle_reserve_ticket(struct btrfs_fs_info *fs_info,
struct btrfs_space_info *space_info,
struct reserve_ticket *ticket,
+ u64 start_ns, u64 orig_bytes,
enum btrfs_reserve_flush_enum flush)
{
int ret;
@@ -1169,6 +1170,8 @@ static int handle_reserve_ticket(struct
* space wasn't reserved at all).
*/
ASSERT(!(ticket->bytes == 0 && ticket->error));
+ trace_btrfs_reserve_ticket(fs_info, space_info->flags, orig_bytes,
+ start_ns, flush, ticket->error);
return ret;
}
@@ -1203,6 +1206,7 @@ static int __reserve_bytes(struct btrfs_
{
struct work_struct *async_work;
struct reserve_ticket ticket;
+ u64 start_ns = 0;
u64 used;
int ret = 0;
bool pending_tickets;
@@ -1256,6 +1260,9 @@ static int __reserve_bytes(struct btrfs_
space_info->reclaim_size += ticket.bytes;
init_waitqueue_head(&ticket.wait);
ticket.steal = (flush == BTRFS_RESERVE_FLUSH_ALL_STEAL);
+ if (trace_btrfs_reserve_ticket_enabled())
+ start_ns = ktime_get_ns();
+
if (flush == BTRFS_RESERVE_FLUSH_ALL ||
flush == BTRFS_RESERVE_FLUSH_ALL_STEAL ||
flush == BTRFS_RESERVE_FLUSH_DATA) {
@@ -1292,7 +1299,8 @@ static int __reserve_bytes(struct btrfs_
if (!ret || flush == BTRFS_RESERVE_NO_FLUSH)
return ret;
- return handle_reserve_ticket(fs_info, space_info, &ticket, flush);
+ return handle_reserve_ticket(fs_info, space_info, &ticket, start_ns,
+ orig_bytes, flush);
}
/**
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -534,6 +534,36 @@ DEFINE_EVENT(btrfs__writepage, __extent_
TP_ARGS(page, inode, wbc)
);
+
+TRACE_EVENT(btrfs_reserve_ticket,
+ TP_PROTO(const struct btrfs_fs_info *fs_info, u64 flags, u64 bytes,
+ u64 start_ns, int flush, int error),
+
+ TP_ARGS(fs_info, flags, bytes, start_ns, flush, error),
+
+ TP_STRUCT__entry_btrfs(
+ __field( u64, flags )
+ __field( u64, bytes )
+ __field( u64, start_ns )
+ __field( int, flush )
+ __field( int, error )
+ ),
+
+ TP_fast_assign_btrfs(fs_info,
+ __entry->flags = flags;
+ __entry->bytes = bytes;
+ __entry->start_ns = start_ns;
+ __entry->flush = flush;
+ __entry->error = error;
+ ),
+
+ TP_printk_btrfs("flags=%s bytes=%llu start_ns=%llu flush=%s error=%d",
+ __print_flags(__entry->flags, "|", BTRFS_GROUP_FLAGS),
+ __entry->bytes, __entry->start_ns,
+ show_flush_action(__entry->flush),
+ __entry->error)
+);
+
TRACE_EVENT(btrfs_writepage_end_io_hook,
TP_PROTO(const struct page *page, u64 start, u64 end, int uptodate),