Commit e131b6aa authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Add a mempool for btree_trans bump allocator

This allocation is required for filesystem operations to make forward
progress, thus needs a mempool.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 9ae28f82
...@@ -644,6 +644,7 @@ struct bch_fs { ...@@ -644,6 +644,7 @@ struct bch_fs {
struct mutex btree_trans_lock; struct mutex btree_trans_lock;
struct list_head btree_trans_list; struct list_head btree_trans_list;
mempool_t btree_iters_pool; mempool_t btree_iters_pool;
mempool_t btree_trans_mem_pool;
struct btree_iter_buf __percpu *btree_iters_bufs; struct btree_iter_buf __percpu *btree_iters_bufs;
struct srcu_struct btree_trans_barrier; struct srcu_struct btree_trans_barrier;
......
...@@ -2181,7 +2181,16 @@ static int bch2_trans_preload_mem(struct btree_trans *trans, size_t size) ...@@ -2181,7 +2181,16 @@ static int bch2_trans_preload_mem(struct btree_trans *trans, size_t size)
if (size > trans->mem_bytes) { if (size > trans->mem_bytes) {
size_t old_bytes = trans->mem_bytes; size_t old_bytes = trans->mem_bytes;
size_t new_bytes = roundup_pow_of_two(size); size_t new_bytes = roundup_pow_of_two(size);
void *new_mem = krealloc(trans->mem, new_bytes, GFP_NOFS); void *new_mem;
WARN_ON_ONCE(new_bytes > BTREE_TRANS_MEM_MAX);
new_mem = krealloc(trans->mem, new_bytes, GFP_NOFS);
if (!new_mem && new_bytes <= BTREE_TRANS_MEM_MAX) {
new_mem = mempool_alloc(&trans->c->btree_trans_mem_pool, GFP_KERNEL);
new_bytes = BTREE_TRANS_MEM_MAX;
kfree(trans->mem);
}
if (!new_mem) if (!new_mem)
return -ENOMEM; return -ENOMEM;
...@@ -2293,9 +2302,14 @@ void bch2_trans_init(struct btree_trans *trans, struct bch_fs *c, ...@@ -2293,9 +2302,14 @@ void bch2_trans_init(struct btree_trans *trans, struct bch_fs *c,
if (expected_mem_bytes) { if (expected_mem_bytes) {
expected_mem_bytes = roundup_pow_of_two(expected_mem_bytes); expected_mem_bytes = roundup_pow_of_two(expected_mem_bytes);
trans->mem = kmalloc(expected_mem_bytes, GFP_KERNEL); trans->mem = kmalloc(expected_mem_bytes, GFP_KERNEL);
if (trans->mem)
if (!unlikely(trans->mem)) {
trans->mem = mempool_alloc(&c->btree_trans_mem_pool, GFP_KERNEL);
trans->mem_bytes = BTREE_TRANS_MEM_MAX;
} else {
trans->mem_bytes = expected_mem_bytes; trans->mem_bytes = expected_mem_bytes;
} }
}
trans->srcu_idx = srcu_read_lock(&c->btree_trans_barrier); trans->srcu_idx = srcu_read_lock(&c->btree_trans_barrier);
...@@ -2324,6 +2338,10 @@ int bch2_trans_exit(struct btree_trans *trans) ...@@ -2324,6 +2338,10 @@ int bch2_trans_exit(struct btree_trans *trans)
bch2_journal_preres_put(&trans->c->journal, &trans->journal_preres); bch2_journal_preres_put(&trans->c->journal, &trans->journal_preres);
kfree(trans->fs_usage_deltas); kfree(trans->fs_usage_deltas);
if (trans->mem_bytes == BTREE_TRANS_MEM_MAX)
mempool_free(trans->mem, &trans->c->btree_trans_mem_pool);
else
kfree(trans->mem); kfree(trans->mem);
#ifdef __KERNEL__ #ifdef __KERNEL__
...@@ -2332,6 +2350,7 @@ int bch2_trans_exit(struct btree_trans *trans) ...@@ -2332,6 +2350,7 @@ int bch2_trans_exit(struct btree_trans *trans)
*/ */
trans->iters = this_cpu_xchg(c->btree_iters_bufs->iter, trans->iters); trans->iters = this_cpu_xchg(c->btree_iters_bufs->iter, trans->iters);
#endif #endif
if (trans->iters) if (trans->iters)
mempool_free(trans->iters, &trans->c->btree_iters_pool); mempool_free(trans->iters, &trans->c->btree_iters_pool);
...@@ -2407,6 +2426,7 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct bch_fs *c) ...@@ -2407,6 +2426,7 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct bch_fs *c)
void bch2_fs_btree_iter_exit(struct bch_fs *c) void bch2_fs_btree_iter_exit(struct bch_fs *c)
{ {
mempool_exit(&c->btree_trans_mem_pool);
mempool_exit(&c->btree_iters_pool); mempool_exit(&c->btree_iters_pool);
cleanup_srcu_struct(&c->btree_trans_barrier); cleanup_srcu_struct(&c->btree_trans_barrier);
} }
...@@ -2422,5 +2442,7 @@ int bch2_fs_btree_iter_init(struct bch_fs *c) ...@@ -2422,5 +2442,7 @@ int bch2_fs_btree_iter_init(struct bch_fs *c)
mempool_init_kmalloc_pool(&c->btree_iters_pool, 1, mempool_init_kmalloc_pool(&c->btree_iters_pool, 1,
sizeof(struct btree_iter) * nr + sizeof(struct btree_iter) * nr +
sizeof(struct btree_insert_entry) * nr + sizeof(struct btree_insert_entry) * nr +
sizeof(struct btree_insert_entry) * nr); sizeof(struct btree_insert_entry) * nr) ?:
mempool_init_kmalloc_pool(&c->btree_trans_mem_pool, 1,
BTREE_TRANS_MEM_MAX);
} }
...@@ -346,6 +346,8 @@ struct btree_insert_entry { ...@@ -346,6 +346,8 @@ struct btree_insert_entry {
#define BTREE_ITER_MAX 32 #define BTREE_ITER_MAX 32
#endif #endif
#define BTREE_TRANS_MEM_MAX (1U << 14)
struct btree_trans { struct btree_trans {
struct bch_fs *c; struct bch_fs *c;
#ifdef CONFIG_BCACHEFS_DEBUG #ifdef CONFIG_BCACHEFS_DEBUG
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment