Skip to content

Commit a592cdf

Browse files
author
Kent Overstreet
committed
bcachefs: don't use rht_bucket() in btree_key_cache_scan()
rht_bucket() does strange complicated things when a rehash is in progress. Instead, just skip scanning when a rehash is in progress: scanning is going to be more expensive (many more empty slots to cover), and some sort of infinite loop is being observed Signed-off-by: Kent Overstreet <[email protected]>
1 parent 3e878fe commit a592cdf

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

fs/bcachefs/btree_key_cache.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -778,14 +778,28 @@ static unsigned long bch2_btree_key_cache_scan(struct shrinker *shrink,
778778

779779
rcu_read_lock();
780780
tbl = rht_dereference_rcu(bc->table.tbl, &bc->table);
781+
782+
/*
783+
* Scanning is expensive while a rehash is in progress - most elements
784+
* will be on the new hashtable, if it's in progress
785+
*
786+
* A rehash could still start while we're scanning - that's ok, we'll
787+
* still see most elements.
788+
*/
789+
if (unlikely(tbl->nest)) {
790+
rcu_read_unlock();
791+
srcu_read_unlock(&c->btree_trans_barrier, srcu_idx);
792+
return SHRINK_STOP;
793+
}
794+
781795
if (bc->shrink_iter >= tbl->size)
782796
bc->shrink_iter = 0;
783797
start = bc->shrink_iter;
784798

785799
do {
786800
struct rhash_head *pos, *next;
787801

788-
pos = rht_ptr_rcu(rht_bucket(tbl, bc->shrink_iter));
802+
pos = rht_ptr_rcu(&tbl->buckets[bc->shrink_iter]);
789803

790804
while (!rht_is_a_nulls(pos)) {
791805
next = rht_dereference_bucket_rcu(pos->next, tbl, bc->shrink_iter);
@@ -866,12 +880,22 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
866880
while (atomic_long_read(&bc->nr_keys)) {
867881
rcu_read_lock();
868882
tbl = rht_dereference_rcu(bc->table.tbl, &bc->table);
869-
if (tbl)
883+
if (tbl) {
884+
if (tbl->nest) {
885+
/* wait for in progress rehash */
886+
rcu_read_unlock();
887+
mutex_lock(&bc->table.mutex);
888+
mutex_unlock(&bc->table.mutex);
889+
rcu_read_lock();
890+
continue;
891+
}
870892
for (i = 0; i < tbl->size; i++)
871-
rht_for_each_entry_rcu(ck, pos, tbl, i, hash) {
893+
while (pos = rht_ptr_rcu(&tbl->buckets[i]), !rht_is_a_nulls(pos)) {
894+
ck = container_of(pos, struct bkey_cached, hash);
872895
bkey_cached_evict(bc, ck);
873896
list_add(&ck->list, &items);
874897
}
898+
}
875899
rcu_read_unlock();
876900
}
877901

0 commit comments

Comments
 (0)