diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-03-02 23:51:47 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:50 -0400 |
commit | 5b3008bc6182e56fdd5ba36fdf324430d0792e0c (patch) | |
tree | 291743193d5101ca8d90a3373e23db6d49149703 | |
parent | 91db80668149a4eb19ab3bfcfecf9f09ad1f2c8f (diff) |
bcachefs: Don't call bch2_journal_pin_drop() under key cache lock
This fixes a (harmless) lockdep splat, due to a lock order violation in
the key cache exit path.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/btree_key_cache.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c index 743ebeba12b1..867f063f22d1 100644 --- a/fs/bcachefs/btree_key_cache.c +++ b/fs/bcachefs/btree_key_cache.c @@ -947,6 +947,7 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc) struct bucket_table *tbl; struct bkey_cached *ck, *n; struct rhash_head *pos; + LIST_HEAD(items); unsigned i; #ifdef __KERNEL__ int cpu; @@ -967,7 +968,7 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc) for (i = 0; i < tbl->size; i++) rht_for_each_entry_rcu(ck, pos, tbl, i, hash) { bkey_cached_evict(bc, ck); - list_add(&ck->list, &bc->freed_nonpcpu); + list_add(&ck->list, &items); } rcu_read_unlock(); } @@ -979,14 +980,17 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc) for (i = 0; i < f->nr; i++) { ck = f->objs[i]; - list_add(&ck->list, &bc->freed_nonpcpu); + list_add(&ck->list, &items); } } #endif - list_splice(&bc->freed_pcpu, &bc->freed_nonpcpu); + list_splice(&bc->freed_pcpu, &items); + list_splice(&bc->freed_nonpcpu, &items); - list_for_each_entry_safe(ck, n, &bc->freed_nonpcpu, list) { + mutex_unlock(&bc->lock); + + list_for_each_entry_safe(ck, n, &items, list) { cond_resched(); bch2_journal_pin_drop(&c->journal, &ck->journal); @@ -1008,8 +1012,6 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc) panic("btree key cache shutdown error: nr_keys nonzero (%li)\n", atomic_long_read(&bc->nr_keys)); - mutex_unlock(&bc->lock); - if (bc->table_init_done) rhashtable_destroy(&bc->table); |