Skip to content

Commit 6088234

Browse files
author
Kent Overstreet
committed
bcachefs: JOURNAL_SPACE_LOW
"bcachefs; Fix deadlock in bch2_btree_update_start()" was a significant performance regression (nearly 50%) on multithreaded random writes with fio. The reason is that the journal watermark checks multiple things, including the state of the btree write buffer, and on multithreaded update heavy workloads we're bottleneked on write buffer flushing - we don't want kicknig off btree updates to depend on the state of the write buffer. This isn't strictly correct; the interior btree update path does do write buffer updates, but it's a tiny fraction of total accounting updates and we're more concerned with space in the journal itself. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 05801b6 commit 6088234

5 files changed

Lines changed: 19 additions & 12 deletions

File tree

fs/bcachefs/btree_key_cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
659659
commit_flags |= BCH_WATERMARK_reclaim;
660660

661661
if (ck->journal.seq != journal_last_seq(j) ||
662-
j->watermark == BCH_WATERMARK_stripe)
662+
!test_bit(JOURNAL_SPACE_LOW, &c->journal.flags))
663663
commit_flags |= BCH_TRANS_COMMIT_no_journal_res;
664664

665665
ret = bch2_btree_iter_traverse(&b_iter) ?:

fs/bcachefs/btree_update_interior.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,18 +1125,14 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
11251125
flags &= ~BCH_WATERMARK_MASK;
11261126
flags |= watermark;
11271127

1128-
if (watermark < c->journal.watermark) {
1129-
struct journal_res res = { 0 };
1130-
unsigned journal_flags = watermark|JOURNAL_RES_GET_CHECK;
1128+
if (watermark < BCH_WATERMARK_reclaim &&
1129+
test_bit(JOURNAL_SPACE_LOW, &c->journal.flags)) {
1130+
if (flags & BCH_TRANS_COMMIT_journal_reclaim)
1131+
return ERR_PTR(-BCH_ERR_journal_reclaim_would_deadlock);
11311132

1132-
if ((flags & BCH_TRANS_COMMIT_journal_reclaim) &&
1133-
watermark < BCH_WATERMARK_reclaim)
1134-
journal_flags |= JOURNAL_RES_GET_NONBLOCK;
1135-
1136-
ret = drop_locks_do(trans,
1137-
bch2_journal_res_get(&c->journal, &res, 1, journal_flags));
1138-
if (bch2_err_matches(ret, BCH_ERR_operation_blocked))
1139-
ret = -BCH_ERR_journal_reclaim_would_deadlock;
1133+
bch2_trans_unlock(trans);
1134+
wait_event(c->journal.wait, !test_bit(JOURNAL_SPACE_LOW, &c->journal.flags));
1135+
ret = bch2_trans_relock(trans);
11401136
if (ret)
11411137
return ERR_PTR(ret);
11421138
}

fs/bcachefs/journal_reclaim.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ void bch2_journal_set_watermark(struct journal *j)
6767
track_event_change(&c->times[BCH_TIME_blocked_write_buffer_full], low_on_wb))
6868
trace_and_count(c, journal_full, c);
6969

70+
mod_bit(JOURNAL_SPACE_LOW, &j->flags, low_on_space || low_on_pin);
71+
7072
swap(watermark, j->watermark);
7173
if (watermark > j->watermark)
7274
journal_wake(j);

fs/bcachefs/journal_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ enum journal_flags {
134134
JOURNAL_STARTED,
135135
JOURNAL_MAY_SKIP_FLUSH,
136136
JOURNAL_NEED_FLUSH_WRITE,
137+
JOURNAL_SPACE_LOW,
137138
};
138139

139140
/* Reasons we may fail to get a journal reservation: */

fs/bcachefs/util.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,14 @@ static inline int copy_from_user_errcode(void *to, const void __user *from, unsi
788788

789789
#endif
790790

791+
static inline void mod_bit(long nr, volatile unsigned long *addr, bool v)
792+
{
793+
if (v)
794+
set_bit(nr, addr);
795+
else
796+
clear_bit(nr, addr);
797+
}
798+
791799
static inline void __set_bit_le64(size_t bit, __le64 *addr)
792800
{
793801
addr[bit / 64] |= cpu_to_le64(BIT_ULL(bit % 64));

0 commit comments

Comments
 (0)