Skip to content

Commit a6548c8

Browse files
author
Kent Overstreet
committed
bcachefs: Avoid flushing the journal in the discard path
When issuing discards, we may need to flush the journal if there's too many buckets that can't be discarded until a journal flush. But the heuristic was bad; we should be comparing the number of buckets that need to flushes against the number of free buckets, not the number of buckets we saw. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 189c176 commit a6548c8

File tree

1 file changed

+41
-19
lines changed

1 file changed

+41
-19
lines changed

fs/bcachefs/alloc_background.c

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,13 +1604,36 @@ int bch2_check_alloc_to_lru_refs(struct bch_fs *c)
16041604
return ret;
16051605
}
16061606

1607+
struct discard_buckets_state {
1608+
u64 seen;
1609+
u64 open;
1610+
u64 need_journal_commit;
1611+
u64 discarded;
1612+
struct bch_dev *ca;
1613+
u64 need_journal_commit_this_dev;
1614+
};
1615+
1616+
static void discard_buckets_next_dev(struct bch_fs *c, struct discard_buckets_state *s, struct bch_dev *ca)
1617+
{
1618+
if (s->ca == ca)
1619+
return;
1620+
1621+
if (s->ca && s->need_journal_commit_this_dev >
1622+
bch2_dev_usage_read(s->ca).d[BCH_DATA_free].buckets)
1623+
bch2_journal_flush_async(&c->journal, NULL);
1624+
1625+
if (s->ca)
1626+
percpu_ref_put(&s->ca->ref);
1627+
if (ca)
1628+
percpu_ref_get(&ca->ref);
1629+
s->ca = ca;
1630+
s->need_journal_commit_this_dev = 0;
1631+
}
1632+
16071633
static int bch2_discard_one_bucket(struct btree_trans *trans,
16081634
struct btree_iter *need_discard_iter,
16091635
struct bpos *discard_pos_done,
1610-
u64 *seen,
1611-
u64 *open,
1612-
u64 *need_journal_commit,
1613-
u64 *discarded)
1636+
struct discard_buckets_state *s)
16141637
{
16151638
struct bch_fs *c = trans->c;
16161639
struct bpos pos = need_discard_iter->pos;
@@ -1622,20 +1645,24 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
16221645
int ret = 0;
16231646

16241647
ca = bch_dev_bkey_exists(c, pos.inode);
1648+
16251649
if (!percpu_ref_tryget(&ca->io_ref)) {
16261650
bch2_btree_iter_set_pos(need_discard_iter, POS(pos.inode + 1, 0));
16271651
return 0;
16281652
}
16291653

1654+
discard_buckets_next_dev(c, s, ca);
1655+
16301656
if (bch2_bucket_is_open_safe(c, pos.inode, pos.offset)) {
1631-
(*open)++;
1657+
s->open++;
16321658
goto out;
16331659
}
16341660

16351661
if (bch2_bucket_needs_journal_commit(&c->buckets_waiting_for_journal,
16361662
c->journal.flushed_seq_ondisk,
16371663
pos.inode, pos.offset)) {
1638-
(*need_journal_commit)++;
1664+
s->need_journal_commit++;
1665+
s->need_journal_commit_this_dev++;
16391666
goto out;
16401667
}
16411668

@@ -1711,9 +1738,9 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
17111738
goto out;
17121739

17131740
count_event(c, bucket_discard);
1714-
(*discarded)++;
1741+
s->discarded++;
17151742
out:
1716-
(*seen)++;
1743+
s->seen++;
17171744
bch2_trans_iter_exit(trans, &iter);
17181745
percpu_ref_put(&ca->io_ref);
17191746
printbuf_exit(&buf);
@@ -1723,7 +1750,7 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
17231750
static void bch2_do_discards_work(struct work_struct *work)
17241751
{
17251752
struct bch_fs *c = container_of(work, struct bch_fs, discard_work);
1726-
u64 seen = 0, open = 0, need_journal_commit = 0, discarded = 0;
1753+
struct discard_buckets_state s = {};
17271754
struct bpos discard_pos_done = POS_MAX;
17281755
int ret;
17291756

@@ -1735,19 +1762,14 @@ static void bch2_do_discards_work(struct work_struct *work)
17351762
ret = bch2_trans_run(c,
17361763
for_each_btree_key(trans, iter,
17371764
BTREE_ID_need_discard, POS_MIN, 0, k,
1738-
bch2_discard_one_bucket(trans, &iter, &discard_pos_done,
1739-
&seen,
1740-
&open,
1741-
&need_journal_commit,
1742-
&discarded)));
1743-
1744-
if (need_journal_commit * 2 > seen)
1745-
bch2_journal_flush_async(&c->journal, NULL);
1765+
bch2_discard_one_bucket(trans, &iter, &discard_pos_done, &s)));
17461766

1747-
bch2_write_ref_put(c, BCH_WRITE_REF_discard);
1767+
discard_buckets_next_dev(c, &s, NULL);
17481768

1749-
trace_discard_buckets(c, seen, open, need_journal_commit, discarded,
1769+
trace_discard_buckets(c, s.seen, s.open, s.need_journal_commit, s.discarded,
17501770
bch2_err_str(ret));
1771+
1772+
bch2_write_ref_put(c, BCH_WRITE_REF_discard);
17511773
}
17521774

17531775
void bch2_do_discards(struct bch_fs *c)

0 commit comments

Comments
 (0)