bcachefs: Fix bch2_btree_cache_scan()
authorKent Overstreet <kent.overstreet@gmail.com>
Tue, 28 Dec 2021 03:11:54 +0000 (22:11 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:55 +0000 (17:08 -0400)
It was counting nodes on the freed list that it skips - because we want
to leave a few so that btree splits don't touch the allocator - as nodes
that it touched, meaning that if it was called with <= 3 nodes to
reclaim, and those nodes were on the freed list, it would never do any
work.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_cache.c

index 2152813554b48d4ad9aea84a7c45f7901ad80270..97b4f87a377fa527f3a0fd5e7da5029b14ece9de 100644 (file)
@@ -281,13 +281,19 @@ static unsigned long bch2_btree_cache_scan(struct shrinker *shrink,
 
        i = 0;
        list_for_each_entry_safe(b, t, &bc->freeable, list) {
+               /*
+                * Leave a few nodes on the freeable list, so that a btree split
+                * won't have to hit the system allocator:
+                */
+               if (++i <= 3)
+                       continue;
+
                touched++;
 
                if (freed >= nr)
                        break;
 
-               if (++i > 3 &&
-                   !btree_node_reclaim(c, b)) {
+               if (!btree_node_reclaim(c, b)) {
                        btree_node_data_free(c, b);
                        six_unlock_write(&b->c.lock);
                        six_unlock_intent(&b->c.lock);