diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-06-27 15:58:48 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-06-27 15:58:48 -0400 |
commit | bad0c8c50758b4447d529f61017c1a8c85976a3e (patch) | |
tree | c27806cdcab52e6697163daeca7b9e903fcd6f64 /libbcachefs/movinggc.c | |
parent | 64ddfc9fc5628f27cdc1399a283452196a7e2dcc (diff) |
Update bcachefs sources to 95ff72a6c1 fixup! mm: Centralize & improve oom reporting in show_mem.c
Diffstat (limited to 'libbcachefs/movinggc.c')
-rw-r--r-- | libbcachefs/movinggc.c | 67 |
1 files changed, 48 insertions, 19 deletions
diff --git a/libbcachefs/movinggc.c b/libbcachefs/movinggc.c index efb09e1c..f9ad4cb2 100644 --- a/libbcachefs/movinggc.c +++ b/libbcachefs/movinggc.c @@ -95,11 +95,11 @@ static int bch2_copygc(struct bch_fs *c) struct bch_dev *ca; unsigned dev_idx; size_t heap_size = 0; - struct data_opts data_opts = { - .nr_replicas = 1, - .btree_insert_flags = BTREE_INSERT_USE_RESERVE|JOURNAL_WATERMARK_copygc, + struct moving_context ctxt; + struct data_update_opts data_opts = { + .btree_insert_flags = BTREE_INSERT_USE_RESERVE|JOURNAL_WATERMARK_copygc, }; - int ret; + int ret = 0; bch_move_stats_init(&move_stats, "copygc"); @@ -121,26 +121,49 @@ static int bch2_copygc(struct bch_fs *c) } if (!h->used) { - bch_err_ratelimited(c, "copygc requested to run but found no buckets to move!"); + s64 wait = S64_MAX, dev_wait; + u64 dev_min_wait_fragmented = 0; + u64 dev_min_wait_allowed = 0; + int dev_min_wait = -1; + + for_each_rw_member(ca, c, dev_idx) { + struct bch_dev_usage usage = bch2_dev_usage_read(ca); + s64 allowed = ((__dev_buckets_available(ca, usage, RESERVE_none) * + ca->mi.bucket_size) >> 1); + s64 fragmented = usage.d[BCH_DATA_user].fragmented; + + dev_wait = max(0LL, allowed - fragmented); + + if (dev_min_wait < 0 || dev_wait < wait) { + dev_min_wait = dev_idx; + dev_min_wait_fragmented = fragmented; + dev_min_wait_allowed = allowed; + } + } + + bch_err_ratelimited(c, "copygc requested to run but found no buckets to move! dev %u fragmented %llu allowed %llu", + dev_min_wait, dev_min_wait_fragmented, dev_min_wait_allowed); return 0; } heap_resort(h, fragmentation_cmp, NULL); - while (h->used) { + bch2_moving_ctxt_init(&ctxt, c, NULL, &move_stats, + writepoint_ptr(&c->copygc_write_point), + false); + + /* not correct w.r.t. device removal */ + while (h->used && !ret) { BUG_ON(!heap_pop(h, e, -fragmentation_cmp, NULL)); - /* not correct w.r.t. device removal */ - - ret = bch2_evacuate_bucket(c, POS(e.dev, e.bucket), e.gen, NULL, - writepoint_ptr(&c->copygc_write_point), - DATA_REWRITE, &data_opts, - &move_stats); - if (ret < 0) - bch_err(c, "error %i from bch2_move_data() in copygc", ret); - if (ret) - return ret; + ret = __bch2_evacuate_bucket(&ctxt, POS(e.dev, e.bucket), e.gen, + data_opts); } + bch2_moving_ctxt_exit(&ctxt); + + if (ret < 0) + bch_err(c, "error %i from bch2_move_data() in copygc", ret); + trace_copygc(c, atomic64_read(&move_stats.sectors_moved), 0, 0, 0); return ret; } @@ -183,10 +206,11 @@ static int bch2_copygc_thread(void *arg) struct bch_fs *c = arg; struct io_clock *clock = &c->io_clock[WRITE]; u64 last, wait; + int ret = 0; set_freezable(); - while (!kthread_should_stop()) { + while (!ret && !kthread_should_stop()) { cond_resched(); if (kthread_wait_freezable(c->copy_gc_enabled)) @@ -205,8 +229,11 @@ static int bch2_copygc_thread(void *arg) c->copygc_wait = 0; - if (bch2_copygc(c)) - break; + c->copygc_running = true; + ret = bch2_copygc(c); + c->copygc_running = false; + + wake_up(&c->copygc_running_wq); } return 0; @@ -250,4 +277,6 @@ int bch2_copygc_start(struct bch_fs *c) void bch2_fs_copygc_init(struct bch_fs *c) { + init_waitqueue_head(&c->copygc_running_wq); + c->copygc_running = false; } |