summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-04-01 16:11:42 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2022-04-02 16:02:57 -0400
commitaee1cfd531e73d06fc94a8166e08dffed9d35327 (patch)
tree53125b86112230199d291e4e91c124102f51691a
parentb9cd9496a25a2ce23d7f9227a1690539fb32f08d (diff)
bcachefs: Discard path fixes/improvements
- bch2_clear_need_discard() was using bch2_trans_relock() incorrectly, and always bailing out before doing any work - ouch. - Add a tracepoint that fires every time bch2_do_discards() runs, and tells us about the work it did - When too many buckets aren't able to be discarded because they need a journal commit, bch2_do_discards now flushes the journal. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/alloc_background.c23
-rw-r--r--include/trace/events/bcachefs.h34
2 files changed, 54 insertions, 3 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
index 1188239a1bcc..e8a34eccac25 100644
--- a/fs/bcachefs/alloc_background.c
+++ b/fs/bcachefs/alloc_background.c
@@ -886,7 +886,7 @@ static int bch2_clear_need_discard(struct btree_trans *trans, struct bpos pos,
GFP_KERNEL, 0);
*discard_done = true;
- ret = bch2_trans_relock(trans);
+ ret = bch2_trans_relock(trans) ? 0 : -EINTR;
if (ret)
goto out;
}
@@ -907,6 +907,7 @@ static void bch2_do_discards_work(struct work_struct *work)
struct btree_trans trans;
struct btree_iter iter;
struct bkey_s_c k;
+ u64 seen = 0, open = 0, need_journal_commit = 0, discarded = 0;
int ret;
bch2_trans_init(&trans, c, 0, 0);
@@ -929,11 +930,19 @@ static void bch2_do_discards_work(struct work_struct *work)
}
}
+ seen++;
+
+ if (bch2_bucket_is_open_safe(c, k.k->p.inode, k.k->p.offset)) {
+ open++;
+ continue;
+ }
+
if (bch2_bucket_needs_journal_commit(&c->buckets_waiting_for_journal,
c->journal.flushed_seq_ondisk,
- k.k->p.inode, k.k->p.offset) ||
- bch2_bucket_is_open_safe(c, k.k->p.inode, k.k->p.offset))
+ k.k->p.inode, k.k->p.offset)) {
+ need_journal_commit++;
continue;
+ }
ret = __bch2_trans_do(&trans, NULL, NULL,
BTREE_INSERT_USE_RESERVE|
@@ -941,6 +950,8 @@ static void bch2_do_discards_work(struct work_struct *work)
bch2_clear_need_discard(&trans, k.k->p, ca, &discard_done));
if (ret)
break;
+
+ discarded++;
}
bch2_trans_iter_exit(&trans, &iter);
@@ -948,7 +959,13 @@ static void bch2_do_discards_work(struct work_struct *work)
percpu_ref_put(&ca->io_ref);
bch2_trans_exit(&trans);
+
+ if (need_journal_commit * 2 > seen)
+ bch2_journal_flush_async(&c->journal, NULL);
+
percpu_ref_put(&c->writes);
+
+ trace_do_discards(c, seen, open, need_journal_commit, discarded, ret);
}
void bch2_do_discards(struct bch_fs *c)
diff --git a/include/trace/events/bcachefs.h b/include/trace/events/bcachefs.h
index bccad83da05b..f63a7c87265d 100644
--- a/include/trace/events/bcachefs.h
+++ b/include/trace/events/bcachefs.h
@@ -182,6 +182,40 @@ TRACE_EVENT(journal_reclaim_finish,
__entry->nr_flushed)
);
+/* allocator: */
+
+TRACE_EVENT(do_discards,
+ TP_PROTO(struct bch_fs *c, u64 seen, u64 open,
+ u64 need_journal_commit, u64 discarded, int ret),
+ TP_ARGS(c, seen, open, need_journal_commit, discarded, ret),
+
+ TP_STRUCT__entry(
+ __field(dev_t, dev )
+ __field(u64, seen )
+ __field(u64, open )
+ __field(u64, need_journal_commit )
+ __field(u64, discarded )
+ __field(int, ret )
+ ),
+
+ TP_fast_assign(
+ __entry->dev = c->dev;
+ __entry->seen = seen;
+ __entry->open = open;
+ __entry->need_journal_commit = need_journal_commit;
+ __entry->discarded = discarded;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("%d%d seen %llu open %llu need_journal_commit %llu discarded %llu ret %i",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->seen,
+ __entry->open,
+ __entry->need_journal_commit,
+ __entry->discarded,
+ __entry->ret)
+);
+
/* bset.c: */
DEFINE_EVENT(bpos, bkey_pack_pos_fail,