diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-11-18 14:09:33 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-05-30 18:15:55 -0400 |
commit | c20242d1e00be732c4740f3b5225365df2d7777d (patch) | |
tree | 412827b77466084c9d2431989830fe900b0aa3eb /fs/bcachefs/btree_key_cache.c | |
parent | b50ca9dd600de569e077c985d6c2de461c32e80c (diff) |
bcachefs: Add a kmem_cache for btree_key_cache objects
We allocate a lot of these, and we're seeing sporading OOMs - this will
help with tracking those down.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/btree_key_cache.c')
-rw-r--r-- | fs/bcachefs/btree_key_cache.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c index d605ff181d2e..9ecd63b50c44 100644 --- a/fs/bcachefs/btree_key_cache.c +++ b/fs/bcachefs/btree_key_cache.c @@ -12,6 +12,8 @@ #include <linux/sched/mm.h> #include <trace/events/bcachefs.h> +static struct kmem_cache *bch2_key_cache; + static int bch2_btree_key_cache_cmp_fn(struct rhashtable_compare_arg *arg, const void *obj) { @@ -104,7 +106,7 @@ bkey_cached_alloc(struct btree_key_cache *c) return ck; } - ck = kzalloc(sizeof(*ck), GFP_NOFS); + ck = kmem_cache_alloc(bch2_key_cache, GFP_NOFS|__GFP_ZERO); if (!ck) return NULL; @@ -515,7 +517,7 @@ static unsigned long bch2_btree_key_cache_scan(struct shrinker *shrink, if (poll_state_synchronize_srcu(&c->btree_trans_barrier, ck->btree_trans_barrier_seq)) { list_del(&ck->list); - kfree(ck); + kmem_cache_free(bch2_key_cache, ck); freed++; } @@ -570,15 +572,18 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc) bch2_journal_preres_put(&c->journal, &ck->res); kfree(ck->k); - kfree(ck); + list_del(&ck->list); + kmem_cache_free(bch2_key_cache, ck); bc->nr_keys--; } BUG_ON(bc->nr_dirty && !bch2_journal_error(&c->journal)); BUG_ON(bc->nr_keys); - list_for_each_entry_safe(ck, n, &bc->freed, list) - kfree(ck); + list_for_each_entry_safe(ck, n, &bc->freed, list) { + list_del(&ck->list); + kmem_cache_free(bch2_key_cache, ck); + } mutex_unlock(&bc->lock); rhashtable_destroy(&bc->table); @@ -624,3 +629,18 @@ void bch2_btree_key_cache_to_text(struct printbuf *out, struct btree_key_cache * } mutex_unlock(&c->lock); } + +void bch2_btree_key_cache_exit(void) +{ + if (bch2_key_cache) + kmem_cache_destroy(bch2_key_cache); +} + +int __init bch2_btree_key_cache_init(void) +{ + bch2_key_cache = KMEM_CACHE(bkey_cached, 0); + if (!bch2_key_cache) + return -ENOMEM; + + return 0; +} |