Skip to content

Commit 1f7056b

Browse files
author
Kent Overstreet
committed
bcachefs: Ensure copygc does not spin
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>
1 parent dc7a15f commit 1f7056b

4 files changed

Lines changed: 34 additions & 8 deletions

File tree

fs/bcachefs/alloc_background.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2085,6 +2085,17 @@ void bch2_recalc_capacity(struct bch_fs *c)
20852085
closure_wake_up(&c->freelist_wait);
20862086
}
20872087

2088+
u64 bch2_min_rw_member_capacity(struct bch_fs *c)
2089+
{
2090+
struct bch_dev *ca;
2091+
unsigned i;
2092+
u64 ret = U64_MAX;
2093+
2094+
for_each_rw_member(ca, c, i)
2095+
ret = min(ret, ca->mi.nbuckets * ca->mi.bucket_size);
2096+
return ret;
2097+
}
2098+
20882099
static bool bch2_dev_has_open_write_point(struct bch_fs *c, struct bch_dev *ca)
20892100
{
20902101
struct open_bucket *ob;

fs/bcachefs/alloc_background.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ int bch2_dev_freespace_init(struct bch_fs *, struct bch_dev *, u64, u64);
249249
int bch2_fs_freespace_init(struct bch_fs *);
250250

251251
void bch2_recalc_capacity(struct bch_fs *);
252+
u64 bch2_min_rw_member_capacity(struct bch_fs *);
252253

253254
void bch2_dev_allocator_remove(struct bch_fs *, struct bch_dev *);
254255
void bch2_dev_allocator_add(struct bch_fs *, struct bch_dev *);

fs/bcachefs/movinggc.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ static int bch2_copygc_get_buckets(struct moving_context *ctxt,
188188

189189
noinline
190190
static int bch2_copygc(struct moving_context *ctxt,
191-
struct buckets_in_flight *buckets_in_flight)
191+
struct buckets_in_flight *buckets_in_flight,
192+
bool *did_work)
192193
{
193194
struct btree_trans *trans = ctxt->trans;
194195
struct bch_fs *c = trans->c;
@@ -224,6 +225,8 @@ static int bch2_copygc(struct moving_context *ctxt,
224225
f->bucket.k.gen, data_opts);
225226
if (ret)
226227
goto err;
228+
229+
*did_work = true;
227230
}
228231
err:
229232
darray_exit(&buckets);
@@ -322,6 +325,8 @@ static int bch2_copygc_thread(void *arg)
322325
false);
323326

324327
while (!ret && !kthread_should_stop()) {
328+
bool did_work = false;
329+
325330
bch2_trans_unlock(ctxt.trans);
326331
cond_resched();
327332

@@ -352,10 +357,21 @@ static int bch2_copygc_thread(void *arg)
352357
c->copygc_wait = 0;
353358

354359
c->copygc_running = true;
355-
ret = bch2_copygc(&ctxt, &buckets);
360+
ret = bch2_copygc(&ctxt, &buckets, &did_work);
356361
c->copygc_running = false;
357362

358363
wake_up(&c->copygc_running_wq);
364+
365+
if (!wait && !did_work) {
366+
u64 min_member_capacity = bch2_min_rw_member_capacity(c);
367+
368+
if (min_member_capacity == U64_MAX)
369+
min_member_capacity = 128 * 2048;
370+
371+
bch2_trans_unlock_long(ctxt.trans);
372+
bch2_kthread_io_clock_wait(clock, last + (min_member_capacity >> 6),
373+
MAX_SCHEDULE_TIMEOUT);
374+
}
359375
}
360376

361377
move_buckets_wait(&ctxt, &buckets, true);

fs/bcachefs/rebalance.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
#include "bcachefs.h"
4+
#include "alloc_background.h"
45
#include "alloc_foreground.h"
56
#include "btree_iter.h"
67
#include "btree_update.h"
@@ -282,15 +283,12 @@ static int do_rebalance_scan(struct moving_context *ctxt, u64 inum, u64 cookie)
282283
static void rebalance_wait(struct bch_fs *c)
283284
{
284285
struct bch_fs_rebalance *r = &c->rebalance;
285-
struct bch_dev *ca;
286286
struct io_clock *clock = &c->io_clock[WRITE];
287287
u64 now = atomic64_read(&clock->now);
288-
u64 min_member_capacity = 128 * 2048;
289-
unsigned i;
288+
u64 min_member_capacity = bch2_min_rw_member_capacity(c);
290289

291-
for_each_rw_member(ca, c, i)
292-
min_member_capacity = min(min_member_capacity,
293-
ca->mi.nbuckets * ca->mi.bucket_size);
290+
if (min_member_capacity == U64_MAX)
291+
min_member_capacity = 128 * 2048;
294292

295293
r->wait_iotime_end = now + (min_member_capacity >> 6);
296294

0 commit comments

Comments
 (0)