Skip to content

Commit e6a2566

Browse files
author
Kent Overstreet
committed
bcachefs: Better journal tracepoints
Factor out bch2_journal_bufs_to_text(), and use it in the journal_entry_full() tracepoint; when we can't get a journal reservation we need to know the outstanding journal entry sizes to know if the problem is due to excessive flushing. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 4ae0166 commit e6a2566

File tree

2 files changed

+79
-60
lines changed

2 files changed

+79
-60
lines changed

fs/bcachefs/journal.c

Lines changed: 72 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,47 @@ static const char * const bch2_journal_errors[] = {
2727
NULL
2828
};
2929

30+
static void bch2_journal_buf_to_text(struct printbuf *out, struct journal *j, u64 seq)
31+
{
32+
union journal_res_state s = READ_ONCE(j->reservations);
33+
unsigned i = seq & JOURNAL_BUF_MASK;
34+
struct journal_buf *buf = j->buf + i;
35+
36+
prt_printf(out, "seq:");
37+
prt_tab(out);
38+
prt_printf(out, "%llu", seq);
39+
prt_newline(out);
40+
printbuf_indent_add(out, 2);
41+
42+
prt_printf(out, "refcount:");
43+
prt_tab(out);
44+
prt_printf(out, "%u", journal_state_count(s, i));
45+
prt_newline(out);
46+
47+
prt_printf(out, "size:");
48+
prt_tab(out);
49+
prt_human_readable_u64(out, vstruct_bytes(buf->data));
50+
prt_newline(out);
51+
52+
prt_printf(out, "expires");
53+
prt_tab(out);
54+
prt_printf(out, "%li jiffies", buf->expires - jiffies);
55+
prt_newline(out);
56+
57+
printbuf_indent_sub(out, 2);
58+
}
59+
60+
static void bch2_journal_bufs_to_text(struct printbuf *out, struct journal *j)
61+
{
62+
if (!out->nr_tabstops)
63+
printbuf_tabstop_push(out, 24);
64+
65+
for (u64 seq = journal_last_unwritten_seq(j);
66+
seq <= journal_cur_seq(j);
67+
seq++)
68+
bch2_journal_buf_to_text(out, j, seq);
69+
}
70+
3071
static inline bool journal_seq_unwritten(struct journal *j, u64 seq)
3172
{
3273
return seq > j->seq_ondisk;
@@ -156,7 +197,7 @@ void bch2_journal_buf_put_final(struct journal *j, u64 seq, bool write)
156197
* We don't close a journal_buf until the next journal_buf is finished writing,
157198
* and can be opened again - this also initializes the next journal_buf:
158199
*/
159-
static void __journal_entry_close(struct journal *j, unsigned closed_val)
200+
static void __journal_entry_close(struct journal *j, unsigned closed_val, bool trace)
160201
{
161202
struct bch_fs *c = container_of(j, struct bch_fs, journal);
162203
struct journal_buf *buf = journal_cur_buf(j);
@@ -185,7 +226,17 @@ static void __journal_entry_close(struct journal *j, unsigned closed_val)
185226
/* Close out old buffer: */
186227
buf->data->u64s = cpu_to_le32(old.cur_entry_offset);
187228

188-
trace_journal_entry_close(c, vstruct_bytes(buf->data));
229+
if (trace_journal_entry_close_enabled() && trace) {
230+
struct printbuf pbuf = PRINTBUF;
231+
pbuf.atomic++;
232+
233+
prt_str(&pbuf, "entry size: ");
234+
prt_human_readable_u64(&pbuf, vstruct_bytes(buf->data));
235+
prt_newline(&pbuf);
236+
bch2_prt_task_backtrace(&pbuf, current, 1);
237+
trace_journal_entry_close(c, pbuf.buf);
238+
printbuf_exit(&pbuf);
239+
}
189240

190241
sectors = vstruct_blocks_plus(buf->data, c->block_bits,
191242
buf->u64s_reserved) << c->block_bits;
@@ -225,7 +276,7 @@ static void __journal_entry_close(struct journal *j, unsigned closed_val)
225276
void bch2_journal_halt(struct journal *j)
226277
{
227278
spin_lock(&j->lock);
228-
__journal_entry_close(j, JOURNAL_ENTRY_ERROR_VAL);
279+
__journal_entry_close(j, JOURNAL_ENTRY_ERROR_VAL, true);
229280
if (!j->err_seq)
230281
j->err_seq = journal_cur_seq(j);
231282
journal_wake(j);
@@ -239,7 +290,7 @@ static bool journal_entry_want_write(struct journal *j)
239290

240291
/* Don't close it yet if we already have a write in flight: */
241292
if (ret)
242-
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL);
293+
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL, true);
243294
else if (nr_unwritten_journal_entries(j)) {
244295
struct journal_buf *buf = journal_cur_buf(j);
245296

@@ -406,7 +457,7 @@ static void journal_write_work(struct work_struct *work)
406457
if (delta > 0)
407458
mod_delayed_work(c->io_complete_wq, &j->write_work, delta);
408459
else
409-
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL);
460+
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL, true);
410461
unlock:
411462
spin_unlock(&j->lock);
412463
}
@@ -463,13 +514,21 @@ static int __journal_res_get(struct journal *j, struct journal_res *res,
463514
buf->buf_size < JOURNAL_ENTRY_SIZE_MAX)
464515
j->buf_size_want = max(j->buf_size_want, buf->buf_size << 1);
465516

466-
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL);
517+
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL, false);
467518
ret = journal_entry_open(j);
468519

469520
if (ret == JOURNAL_ERR_max_in_flight) {
470521
track_event_change(&c->times[BCH_TIME_blocked_journal_max_in_flight],
471522
&j->max_in_flight_start, true);
472-
trace_and_count(c, journal_entry_full, c);
523+
if (trace_journal_entry_full_enabled()) {
524+
struct printbuf buf = PRINTBUF;
525+
buf.atomic++;
526+
527+
bch2_journal_bufs_to_text(&buf, j);
528+
trace_journal_entry_full(c, buf.buf);
529+
printbuf_exit(&buf);
530+
}
531+
count_event(c, journal_entry_full);
473532
}
474533
unlock:
475534
can_discard = j->can_discard;
@@ -549,7 +608,7 @@ void bch2_journal_entry_res_resize(struct journal *j,
549608
/*
550609
* Not enough room in current journal entry, have to flush it:
551610
*/
552-
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL);
611+
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL, true);
553612
} else {
554613
journal_cur_buf(j)->u64s_reserved += d;
555614
}
@@ -606,7 +665,7 @@ int bch2_journal_flush_seq_async(struct journal *j, u64 seq,
606665
struct journal_res res = { 0 };
607666

608667
if (journal_entry_is_open(j))
609-
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL);
668+
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL, true);
610669

611670
spin_unlock(&j->lock);
612671

@@ -786,7 +845,7 @@ static struct journal_buf *__bch2_next_write_buffer_flush_journal_buf(struct jou
786845

787846
if (buf->need_flush_to_write_buffer) {
788847
if (seq == journal_cur_seq(j))
789-
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL);
848+
__journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL, true);
790849

791850
union journal_res_state s;
792851
s.v = atomic64_read_acquire(&j->reservations.counter);
@@ -1339,35 +1398,9 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j)
13391398
}
13401399

13411400
prt_newline(out);
1342-
1343-
for (u64 seq = journal_cur_seq(j);
1344-
seq >= journal_last_unwritten_seq(j);
1345-
--seq) {
1346-
unsigned i = seq & JOURNAL_BUF_MASK;
1347-
1348-
prt_printf(out, "unwritten entry:");
1349-
prt_tab(out);
1350-
prt_printf(out, "%llu", seq);
1351-
prt_newline(out);
1352-
printbuf_indent_add(out, 2);
1353-
1354-
prt_printf(out, "refcount:");
1355-
prt_tab(out);
1356-
prt_printf(out, "%u", journal_state_count(s, i));
1357-
prt_newline(out);
1358-
1359-
prt_printf(out, "sectors:");
1360-
prt_tab(out);
1361-
prt_printf(out, "%u", j->buf[i].sectors);
1362-
prt_newline(out);
1363-
1364-
prt_printf(out, "expires");
1365-
prt_tab(out);
1366-
prt_printf(out, "%li jiffies", j->buf[i].expires - jiffies);
1367-
prt_newline(out);
1368-
1369-
printbuf_indent_sub(out, 2);
1370-
}
1401+
prt_printf(out, "unwritten entries:");
1402+
prt_newline(out);
1403+
bch2_journal_bufs_to_text(out, j);
13711404

13721405
prt_printf(out,
13731406
"replay done:\t\t%i\n",

fs/bcachefs/trace.h

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ DECLARE_EVENT_CLASS(fs_str,
4646
__assign_str(str, str);
4747
),
4848

49-
TP_printk("%d,%d %s", MAJOR(__entry->dev), MINOR(__entry->dev), __get_str(str))
49+
TP_printk("%d,%d\n%s", MAJOR(__entry->dev), MINOR(__entry->dev), __get_str(str))
5050
);
5151

5252
DECLARE_EVENT_CLASS(trans_str,
@@ -273,28 +273,14 @@ DEFINE_EVENT(bch_fs, journal_full,
273273
TP_ARGS(c)
274274
);
275275

276-
DEFINE_EVENT(bch_fs, journal_entry_full,
277-
TP_PROTO(struct bch_fs *c),
278-
TP_ARGS(c)
276+
DEFINE_EVENT(fs_str, journal_entry_full,
277+
TP_PROTO(struct bch_fs *c, const char *str),
278+
TP_ARGS(c, str)
279279
);
280280

281-
TRACE_EVENT(journal_entry_close,
282-
TP_PROTO(struct bch_fs *c, unsigned bytes),
283-
TP_ARGS(c, bytes),
284-
285-
TP_STRUCT__entry(
286-
__field(dev_t, dev )
287-
__field(u32, bytes )
288-
),
289-
290-
TP_fast_assign(
291-
__entry->dev = c->dev;
292-
__entry->bytes = bytes;
293-
),
294-
295-
TP_printk("%d,%d entry bytes %u",
296-
MAJOR(__entry->dev), MINOR(__entry->dev),
297-
__entry->bytes)
281+
DEFINE_EVENT(fs_str, journal_entry_close,
282+
TP_PROTO(struct bch_fs *c, const char *str),
283+
TP_ARGS(c, str)
298284
);
299285

300286
DEFINE_EVENT(bio, journal_write,

0 commit comments

Comments
 (0)