diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-04-01 16:11:42 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-04-02 16:02:57 -0400 |
commit | aee1cfd531e73d06fc94a8166e08dffed9d35327 (patch) | |
tree | 53125b86112230199d291e4e91c124102f51691a | |
parent | b9cd9496a25a2ce23d7f9227a1690539fb32f08d (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.c | 23 | ||||
-rw-r--r-- | include/trace/events/bcachefs.h | 34 |
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, |