Skip to content

Commit

Permalink
bcachefs: Coalesce accounting keys before journal replay
Browse files Browse the repository at this point in the history
This fixes a performance regression in journal replay; without
colaescing accounting keys we have multiple keys at the same position,
which means journal_keys_peek_upto() has to skip past many overwritten
keys - turning journal replay into an O(n^2) algorithm.

Signed-off-by: Kent Overstreet <[email protected]>
  • Loading branch information
Kent Overstreet committed Jun 5, 2024
1 parent 953040b commit c54521c
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions fs/bcachefs/disk_accounting.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "bcachefs.h"
#include "bcachefs_ioctl.h"
#include "btree_cache.h"
#include "btree_journal_iter.h"
#include "btree_update.h"
#include "btree_write_buffer.h"
#include "buckets.h"
Expand Down Expand Up @@ -548,7 +549,9 @@ int bch2_accounting_read(struct bch_fs *c)
goto err;

struct journal_keys *keys = &c->journal_keys;
struct journal_key *dst = keys->data;
move_gap(keys, keys->nr);

darray_for_each(*keys, i) {
if (i->k->k.type == KEY_TYPE_accounting) {
struct bkey_s_c k = bkey_i_to_s_c(i->k);
Expand All @@ -562,11 +565,26 @@ int bch2_accounting_read(struct bch_fs *c)
if (applied)
continue;

if (i + 1 < &darray_top(*keys) &&
i[1].k->k.type == KEY_TYPE_accounting &&
!journal_key_cmp(i, i + 1)) {
BUG_ON(bversion_cmp(i[0].k->k.version, i[1].k->k.version) >= 0);

i[1].journal_seq = i[0].journal_seq;

bch2_accounting_accumulate(bkey_i_to_accounting(i[1].k),
bkey_s_c_to_accounting(k));
continue;
}

ret = accounting_read_key(c, NULL, k);
if (ret)
goto err;
}

*dst++ = *i;
}
keys->gap = keys->nr = dst - keys->data;

percpu_down_read(&c->mark_lock);
preempt_disable();
Expand Down

0 comments on commit c54521c

Please sign in to comment.