bcachefs: Don't wait for ALLOC_SCAN_BATCH buckets in allocator
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 8 Apr 2021 01:04:04 +0000 (21:04 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:59 +0000 (17:08 -0400)
It used to be necessary for the allocator thread to batch up
invalidating buckets when possible - but since we added the btree key
cache that hasn't been a concern, and now it's causing the allocator
thread to livelock when the filesystem is nearly full.

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

index be86e36e816a837b5953ee51ae17450148d7b048..a8a59140efbeb8e2f667afc25fc9d052548b8983 100644 (file)
@@ -1071,7 +1071,7 @@ static int bch2_allocator_thread(void *arg)
 
                pr_debug("free_inc now empty");
 
-               do {
+               while (1) {
                        cond_resched();
                        /*
                         * Find some buckets that we can invalidate, either
@@ -1095,22 +1095,21 @@ static int bch2_allocator_thread(void *arg)
                                wake_up_process(c->gc_thread);
                        }
 
+                       if (nr)
+                               break;
+
                        /*
                         * If we found any buckets, we have to invalidate them
                         * before we scan for more - but if we didn't find very
                         * many we may want to wait on more buckets being
                         * available so we don't spin:
                         */
-                       if (!nr ||
-                           (nr < ALLOC_SCAN_BATCH(ca) &&
-                            !fifo_empty(&ca->free[RESERVE_NONE]))) {
-                               ret = wait_buckets_available(c, ca);
-                               if (ret) {
-                                       up_read(&c->gc_lock);
-                                       goto stop;
-                               }
+                       ret = wait_buckets_available(c, ca);
+                       if (ret) {
+                               up_read(&c->gc_lock);
+                               goto stop;
                        }
-               } while (!nr);
+               }
 
                up_read(&c->gc_lock);