From 14ba3706b3a8b5d243e0f250e54baeaecfbd8289 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@gmail.com> Date: Wed, 18 Nov 2020 14:09:33 -0500 Subject: [PATCH] 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> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/btree_key_cache.c | 30 +++++++++++++++++++++++++----- fs/bcachefs/btree_key_cache.h | 3 +++ fs/bcachefs/super.c | 2 ++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c index 71d5bfa4caab..441cdc88b940 100644 --- a/fs/bcachefs/btree_key_cache.c +++ b/fs/bcachefs/btree_key_cache.c @@ -12,6 +12,8 @@ #include <linux/sched/mm.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; @@ -516,7 +518,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++; } @@ -571,15 +573,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); @@ -627,3 +632,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; +} diff --git a/fs/bcachefs/btree_key_cache.h b/fs/bcachefs/btree_key_cache.h index d448264abcc8..e64a8e9c726f 100644 --- a/fs/bcachefs/btree_key_cache.h +++ b/fs/bcachefs/btree_key_cache.h @@ -25,4 +25,7 @@ int bch2_fs_btree_key_cache_init(struct btree_key_cache *); void bch2_btree_key_cache_to_text(struct printbuf *, struct btree_key_cache *); +void bch2_btree_key_cache_exit(void); +int __init bch2_btree_key_cache_init(void); + #endif /* _BCACHEFS_BTREE_KEY_CACHE_H */ diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 61b7e750037c..12ce4a627746 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -2020,6 +2020,7 @@ static void bcachefs_exit(void) bch2_debug_exit(); bch2_vfs_exit(); bch2_chardev_exit(); + bch2_btree_key_cache_exit(); if (bcachefs_kset) kset_unregister(bcachefs_kset); } @@ -2029,6 +2030,7 @@ static int __init bcachefs_init(void) bch2_bkey_pack_test(); if (!(bcachefs_kset = kset_create_and_add("bcachefs", NULL, fs_kobj)) || + bch2_btree_key_cache_init() || bch2_chardev_init() || bch2_vfs_init() || bch2_debug_init()) -- 2.30.9