summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-09-26 16:19:56 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2022-10-03 23:55:33 -0400
commitd8beda54bfa8106899964d5ce9e4ab288706be93 (patch)
tree84d7686ee8f7b729e59f63f21858914c3be7e00d
parent243aed1561b6ce17b529160d4fbd435be4a5c926 (diff)
bcachefs: Optimize btree_path_alloc()
- move slowpath code to a separate function, btree_path_overflow() - no need to use hweight64 - copy nr_max_paths from btree_transaction_stats to btree_trans, avoiding a data dependency in the fast path Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/btree_iter.c23
-rw-r--r--fs/bcachefs/btree_types.h1
2 files changed, 15 insertions, 9 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 390758d004fe..fc3542e3e72b 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -1407,7 +1407,8 @@ static void bch2_trans_update_max_paths(struct btree_trans *trans)
if (!buf.allocation_failure) {
mutex_lock(&s->lock);
if (s->nr_max_paths < hweight64(trans->paths_allocated)) {
- s->nr_max_paths = hweight64(trans->paths_allocated);
+ s->nr_max_paths = trans->nr_max_paths =
+ hweight64(trans->paths_allocated);
swap(s->max_paths_text, buf.buf);
}
mutex_unlock(&s->lock);
@@ -1416,23 +1417,26 @@ static void bch2_trans_update_max_paths(struct btree_trans *trans)
printbuf_exit(&buf);
}
-static struct btree_path *btree_path_alloc(struct btree_trans *trans,
- struct btree_path *pos)
+static noinline void btree_path_overflow(struct btree_trans *trans)
+{
+ bch2_dump_trans_paths_updates(trans);
+ panic("trans path oveflow\n");
+}
+
+static inline struct btree_path *btree_path_alloc(struct btree_trans *trans,
+ struct btree_path *pos)
{
- struct btree_transaction_stats *s = btree_trans_stats(trans);
struct btree_path *path;
unsigned idx;
if (unlikely(trans->paths_allocated ==
- ~((~0ULL << 1) << (BTREE_ITER_MAX - 1)))) {
- bch2_dump_trans_paths_updates(trans);
- panic("trans path oveflow\n");
- }
+ ~((~0ULL << 1) << (BTREE_ITER_MAX - 1))))
+ btree_path_overflow(trans);
idx = __ffs64(~trans->paths_allocated);
trans->paths_allocated |= 1ULL << idx;
- if (s && unlikely(hweight64(trans->paths_allocated) > s->nr_max_paths))
+ if (unlikely(idx > trans->nr_max_paths))
bch2_trans_update_max_paths(trans);
path = &trans->paths[idx];
@@ -2832,6 +2836,7 @@ void __bch2_trans_init(struct btree_trans *trans, struct bch_fs *c, const char *
trans->mem_bytes = roundup_pow_of_two(expected_mem_bytes);
trans->mem = kmalloc(trans->mem_bytes, GFP_KERNEL|__GFP_NOFAIL);
+ trans->nr_max_paths = s->nr_max_paths;
if (!unlikely(trans->mem)) {
trans->mem = mempool_alloc(&c->btree_trans_mem_pool, GFP_KERNEL);
diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h
index f6aee115e828..af226eed818b 100644
--- a/fs/bcachefs/btree_types.h
+++ b/fs/bcachefs/btree_types.h
@@ -417,6 +417,7 @@ struct btree_trans {
* extent:
*/
unsigned extra_journal_res;
+ unsigned nr_max_paths;
u64 paths_allocated;