summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-10-30 13:15:36 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-30 13:51:47 -0400
commit08398d3534d8cdba7d90d2e37ac8bdb3e143dedf (patch)
tree5958532877643e1ca12e949416dc43360d4b4a86
parent6628827a87075d3f807c974045ed293ac1e8965b (diff)
bcachefs: Ensure copygc does not spinbcachefs-v6.5
If copygc does no work - finds no fragmented buckets - wait for a bit of IO to happen. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/alloc_background.c11
-rw-r--r--fs/bcachefs/alloc_background.h1
-rw-r--r--fs/bcachefs/movinggc.c19
-rw-r--r--fs/bcachefs/rebalance.c10
4 files changed, 33 insertions, 8 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
index c342ec3b0385..bcfae91667af 100644
--- a/fs/bcachefs/alloc_background.c
+++ b/fs/bcachefs/alloc_background.c
@@ -2085,6 +2085,17 @@ void bch2_recalc_capacity(struct bch_fs *c)
closure_wake_up(&c->freelist_wait);
}
+u64 bch2_min_rw_member_capacity(struct bch_fs *c)
+{
+ struct bch_dev *ca;
+ unsigned i;
+ u64 ret = U64_MAX;
+
+ for_each_rw_member(ca, c, i)
+ ret = min(ret, ca->mi.nbuckets * ca->mi.bucket_size);
+ return ret;
+}
+
static bool bch2_dev_has_open_write_point(struct bch_fs *c, struct bch_dev *ca)
{
struct open_bucket *ob;
diff --git a/fs/bcachefs/alloc_background.h b/fs/bcachefs/alloc_background.h
index e1ce38ef052e..73faf99a222a 100644
--- a/fs/bcachefs/alloc_background.h
+++ b/fs/bcachefs/alloc_background.h
@@ -249,6 +249,7 @@ int bch2_dev_freespace_init(struct bch_fs *, struct bch_dev *, u64, u64);
int bch2_fs_freespace_init(struct bch_fs *);
void bch2_recalc_capacity(struct bch_fs *);
+u64 bch2_min_rw_member_capacity(struct bch_fs *);
void bch2_dev_allocator_remove(struct bch_fs *, struct bch_dev *);
void bch2_dev_allocator_add(struct bch_fs *, struct bch_dev *);
diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c
index f73b9b7f4bf7..986d7ffbe486 100644
--- a/fs/bcachefs/movinggc.c
+++ b/fs/bcachefs/movinggc.c
@@ -188,7 +188,8 @@ static int bch2_copygc_get_buckets(struct moving_context *ctxt,
noinline
static int bch2_copygc(struct moving_context *ctxt,
- struct buckets_in_flight *buckets_in_flight)
+ struct buckets_in_flight *buckets_in_flight,
+ bool *did_work)
{
struct btree_trans *trans = ctxt->trans;
struct bch_fs *c = trans->c;
@@ -224,6 +225,8 @@ static int bch2_copygc(struct moving_context *ctxt,
f->bucket.k.gen, data_opts);
if (ret)
goto err;
+
+ *did_work = true;
}
err:
darray_exit(&buckets);
@@ -322,6 +325,8 @@ static int bch2_copygc_thread(void *arg)
false);
while (!ret && !kthread_should_stop()) {
+ bool did_work = false;
+
bch2_trans_unlock(ctxt.trans);
cond_resched();
@@ -352,10 +357,20 @@ static int bch2_copygc_thread(void *arg)
c->copygc_wait = 0;
c->copygc_running = true;
- ret = bch2_copygc(&ctxt, &buckets);
+ ret = bch2_copygc(&ctxt, &buckets, &did_work);
c->copygc_running = false;
wake_up(&c->copygc_running_wq);
+
+ if (!wait && !did_work) {
+ u64 min_member_capacity = bch2_min_rw_member_capacity(c);
+
+ if (min_member_capacity == U64_MAX)
+ min_member_capacity = 128 * 2048;
+
+ bch2_kthread_io_clock_wait(clock, last + (min_member_capacity >> 6),
+ MAX_SCHEDULE_TIMEOUT);
+ }
}
move_buckets_wait(&ctxt, &buckets, true);
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
index 6ee4d2e02073..82014cc6e271 100644
--- a/fs/bcachefs/rebalance.c
+++ b/fs/bcachefs/rebalance.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include "bcachefs.h"
+#include "alloc_background.h"
#include "alloc_foreground.h"
#include "btree_iter.h"
#include "btree_update.h"
@@ -282,15 +283,12 @@ static int do_rebalance_scan(struct moving_context *ctxt, u64 inum, u64 cookie)
static void rebalance_wait(struct bch_fs *c)
{
struct bch_fs_rebalance *r = &c->rebalance;
- struct bch_dev *ca;
struct io_clock *clock = &c->io_clock[WRITE];
u64 now = atomic64_read(&clock->now);
- u64 min_member_capacity = 128 * 2048;
- unsigned i;
+ u64 min_member_capacity = bch2_min_rw_member_capacity(c);
- for_each_rw_member(ca, c, i)
- min_member_capacity = min(min_member_capacity,
- ca->mi.nbuckets * ca->mi.bucket_size);
+ if (min_member_capacity == U64_MAX)
+ min_member_capacity = 128 * 2048;
r->wait_iotime_end = now + (min_member_capacity >> 6);