Skip to content

Commit 4057494

Browse files
author
Kent Overstreet
committed
bcachefs: Better bucket alloc tracepoints
Tracepoints are garbage, and perf trace even cuts off some of our fields. Much nicer to just trace a string, and then we can build nicely formatted output with printbufs. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 6202569 commit 4057494

File tree

2 files changed

+51
-111
lines changed

2 files changed

+51
-111
lines changed

fs/bcachefs/alloc_foreground.c

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,44 @@ static struct open_bucket *bch2_bucket_alloc_freelist(struct btree_trans *trans,
511511
return ob;
512512
}
513513

514+
static noinline void trace_bucket_alloc2(struct bch_fs *c, struct bch_dev *ca,
515+
enum bch_watermark watermark,
516+
enum bch_data_type data_type,
517+
struct closure *cl,
518+
struct bch_dev_usage *usage,
519+
struct bucket_alloc_state *s,
520+
struct open_bucket *ob)
521+
{
522+
struct printbuf buf = PRINTBUF;
523+
524+
printbuf_tabstop_push(&buf, 24);
525+
526+
prt_printf(&buf, "dev\t%s (%u)\n", ca->name, ca->dev_idx);
527+
prt_printf(&buf, "watermark\t%s\n", bch2_watermarks[watermark]);
528+
prt_printf(&buf, "data type\t%s\n", __bch2_data_types[data_type]);
529+
prt_printf(&buf, "blocking\t%u\n", cl != NULL);
530+
prt_printf(&buf, "free\t%llu\n", usage->d[BCH_DATA_free].buckets);
531+
prt_printf(&buf, "avail\t%llu\n", dev_buckets_free(ca, *usage, watermark));
532+
prt_printf(&buf, "copygc_wait\t%lu/%lli\n",
533+
bch2_copygc_wait_amount(c),
534+
c->copygc_wait - atomic64_read(&c->io_clock[WRITE].now));
535+
prt_printf(&buf, "seen\t%llu\n", s->buckets_seen);
536+
prt_printf(&buf, "open\t%llu\n", s->skipped_open);
537+
prt_printf(&buf, "need journal commit\t%llu\n", s->skipped_need_journal_commit);
538+
prt_printf(&buf, "nocow\t%llu\n", s->skipped_nocow);
539+
prt_printf(&buf, "nouse\t%llu\n", s->skipped_nouse);
540+
541+
if (!IS_ERR(ob)) {
542+
prt_printf(&buf, "allocated\t%llu\n", ob->bucket);
543+
trace_bucket_alloc(c, buf.buf);
544+
} else {
545+
prt_printf(&buf, "err\t%s\n", bch2_err_str(PTR_ERR(ob)));
546+
trace_bucket_alloc_fail(c, buf.buf);
547+
}
548+
549+
printbuf_exit(&buf);
550+
}
551+
514552
/**
515553
* bch2_bucket_alloc_trans - allocate a single bucket from a specific device
516554
* @trans: transaction object
@@ -583,27 +621,14 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans,
583621
ob->data_type = data_type;
584622

585623
if (!IS_ERR(ob))
586-
trace_and_count(c, bucket_alloc, ca,
587-
bch2_watermarks[watermark],
588-
ob->bucket,
589-
usage->d[BCH_DATA_free].buckets,
590-
avail,
591-
bch2_copygc_wait_amount(c),
592-
c->copygc_wait - atomic64_read(&c->io_clock[WRITE].now),
593-
&s,
594-
cl == NULL,
595-
"");
624+
count_event(c, bucket_alloc);
596625
else if (!bch2_err_matches(PTR_ERR(ob), BCH_ERR_transaction_restart))
597-
trace_and_count(c, bucket_alloc_fail, ca,
598-
bch2_watermarks[watermark],
599-
0,
600-
usage->d[BCH_DATA_free].buckets,
601-
avail,
602-
bch2_copygc_wait_amount(c),
603-
c->copygc_wait - atomic64_read(&c->io_clock[WRITE].now),
604-
&s,
605-
cl == NULL,
606-
bch2_err_str(PTR_ERR(ob)));
626+
count_event(c, bucket_alloc_fail);
627+
628+
if (!IS_ERR(ob)
629+
? trace_bucket_alloc_enabled()
630+
: trace_bucket_alloc_fail_enabled())
631+
trace_bucket_alloc2(c, ca, watermark, data_type, cl, usage, &s, ob);
607632

608633
return ob;
609634
}

fs/bcachefs/trace.h

Lines changed: 6 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -638,99 +638,14 @@ DEFINE_EVENT(bch_fs, gc_gens_end,
638638

639639
/* Allocator */
640640

641-
DECLARE_EVENT_CLASS(bucket_alloc,
642-
TP_PROTO(struct bch_dev *ca, const char *alloc_reserve,
643-
u64 bucket,
644-
u64 free,
645-
u64 avail,
646-
u64 copygc_wait_amount,
647-
s64 copygc_waiting_for,
648-
struct bucket_alloc_state *s,
649-
bool nonblocking,
650-
const char *err),
651-
TP_ARGS(ca, alloc_reserve, bucket, free, avail,
652-
copygc_wait_amount, copygc_waiting_for,
653-
s, nonblocking, err),
654-
655-
TP_STRUCT__entry(
656-
__field(u8, dev )
657-
__array(char, reserve, 16 )
658-
__field(u64, bucket )
659-
__field(u64, free )
660-
__field(u64, avail )
661-
__field(u64, copygc_wait_amount )
662-
__field(s64, copygc_waiting_for )
663-
__field(u64, seen )
664-
__field(u64, open )
665-
__field(u64, need_journal_commit )
666-
__field(u64, nouse )
667-
__field(bool, nonblocking )
668-
__field(u64, nocow )
669-
__array(char, err, 32 )
670-
),
671-
672-
TP_fast_assign(
673-
__entry->dev = ca->dev_idx;
674-
strscpy(__entry->reserve, alloc_reserve, sizeof(__entry->reserve));
675-
__entry->bucket = bucket;
676-
__entry->free = free;
677-
__entry->avail = avail;
678-
__entry->copygc_wait_amount = copygc_wait_amount;
679-
__entry->copygc_waiting_for = copygc_waiting_for;
680-
__entry->seen = s->buckets_seen;
681-
__entry->open = s->skipped_open;
682-
__entry->need_journal_commit = s->skipped_need_journal_commit;
683-
__entry->nouse = s->skipped_nouse;
684-
__entry->nonblocking = nonblocking;
685-
__entry->nocow = s->skipped_nocow;
686-
strscpy(__entry->err, err, sizeof(__entry->err));
687-
),
688-
689-
TP_printk("reserve %s bucket %u:%llu free %llu avail %llu copygc_wait %llu/%lli seen %llu open %llu need_journal_commit %llu nouse %llu nocow %llu nonblocking %u err %s",
690-
__entry->reserve,
691-
__entry->dev,
692-
__entry->bucket,
693-
__entry->free,
694-
__entry->avail,
695-
__entry->copygc_wait_amount,
696-
__entry->copygc_waiting_for,
697-
__entry->seen,
698-
__entry->open,
699-
__entry->need_journal_commit,
700-
__entry->nouse,
701-
__entry->nocow,
702-
__entry->nonblocking,
703-
__entry->err)
641+
DEFINE_EVENT(fs_str, bucket_alloc,
642+
TP_PROTO(struct bch_fs *c, const char *str),
643+
TP_ARGS(c, str)
704644
);
705645

706-
DEFINE_EVENT(bucket_alloc, bucket_alloc,
707-
TP_PROTO(struct bch_dev *ca, const char *alloc_reserve,
708-
u64 bucket,
709-
u64 free,
710-
u64 avail,
711-
u64 copygc_wait_amount,
712-
s64 copygc_waiting_for,
713-
struct bucket_alloc_state *s,
714-
bool nonblocking,
715-
const char *err),
716-
TP_ARGS(ca, alloc_reserve, bucket, free, avail,
717-
copygc_wait_amount, copygc_waiting_for,
718-
s, nonblocking, err)
719-
);
720-
721-
DEFINE_EVENT(bucket_alloc, bucket_alloc_fail,
722-
TP_PROTO(struct bch_dev *ca, const char *alloc_reserve,
723-
u64 bucket,
724-
u64 free,
725-
u64 avail,
726-
u64 copygc_wait_amount,
727-
s64 copygc_waiting_for,
728-
struct bucket_alloc_state *s,
729-
bool nonblocking,
730-
const char *err),
731-
TP_ARGS(ca, alloc_reserve, bucket, free, avail,
732-
copygc_wait_amount, copygc_waiting_for,
733-
s, nonblocking, err)
646+
DEFINE_EVENT(fs_str, bucket_alloc_fail,
647+
TP_PROTO(struct bch_fs *c, const char *str),
648+
TP_ARGS(c, str)
734649
);
735650

736651
TRACE_EVENT(discard_buckets,

0 commit comments

Comments
 (0)