From 8dd6ed9451894e2168328e2203d227303b472ca3 Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Fri, 23 Jul 2021 13:57:19 -0600 Subject: [PATCH] bcachefs: add progress stats to sysfs This adds progress stats to sysfs for copygc, rebalance, recovery, and the cmd_job ioctls. Signed-off-by: Brett Holman Signed-off-by: Kent Overstreet --- fs/bcachefs/bcachefs.h | 4 ++++ fs/bcachefs/move.c | 31 +++++++++++++++++++++++++++ fs/bcachefs/move.h | 4 ++++ fs/bcachefs/move_types.h | 2 ++ fs/bcachefs/movinggc.c | 3 ++- fs/bcachefs/rebalance.c | 11 +++++----- fs/bcachefs/rebalance_types.h | 1 - fs/bcachefs/recovery.c | 4 +++- fs/bcachefs/super.c | 3 +++ fs/bcachefs/sysfs.c | 40 +++++++++++++++++++++++++++++++++++ 10 files changed, 94 insertions(+), 9 deletions(-) diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index 6a289b6f1fb4d..e2aac1da18ae5 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -792,6 +792,10 @@ mempool_t bio_bounce_pages; struct write_point copygc_write_point; s64 copygc_wait; + /* DATA PROGRESS STATS */ + struct list_head data_progress_list; + struct mutex data_progress_lock; + /* STRIPES: */ GENRADIX(struct stripe) stripes[2]; diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index 9a423a3e4570d..8d28d8fc5395e 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -686,6 +686,30 @@ out: return ret; } +inline void bch_move_stats_init(struct bch_move_stats *stats, char *name) +{ + memset(stats, 0, sizeof(*stats)); + + scnprintf(stats->name, sizeof(stats->name), + "%s", name); +} + +static inline void progress_list_add(struct bch_fs *c, + struct bch_move_stats *stats) +{ + mutex_lock(&c->data_progress_lock); + list_add(&stats->list, &c->data_progress_list); + mutex_unlock(&c->data_progress_lock); +} + +static inline void progress_list_del(struct bch_fs *c, + struct bch_move_stats *stats) +{ + mutex_lock(&c->data_progress_lock); + list_del(&stats->list); + mutex_unlock(&c->data_progress_lock); +} + int bch2_move_data(struct bch_fs *c, enum btree_id start_btree_id, struct bpos start_pos, enum btree_id end_btree_id, struct bpos end_pos, @@ -698,6 +722,7 @@ int bch2_move_data(struct bch_fs *c, enum btree_id id; int ret; + progress_list_add(c, stats); closure_init_stack(&ctxt.cl); INIT_LIST_HEAD(&ctxt.reads); init_waitqueue_head(&ctxt.wait); @@ -731,6 +756,7 @@ int bch2_move_data(struct bch_fs *c, atomic64_read(&stats->sectors_moved), atomic64_read(&stats->keys_moved)); + progress_list_del(c, stats); return ret; } @@ -755,6 +781,7 @@ static int bch2_move_btree(struct bch_fs *c, int ret = 0; bch2_trans_init(&trans, c, 0, 0); + progress_list_add(c, stats); stats->data_type = BCH_DATA_btree; @@ -803,6 +830,7 @@ next: if (ret) bch_err(c, "error %i in bch2_move_btree", ret); + progress_list_del(c, stats); return ret; } @@ -944,6 +972,7 @@ int bch2_data_job(struct bch_fs *c, switch (op.op) { case BCH_DATA_OP_REREPLICATE: + bch_move_stats_init(stats, "rereplicate"); stats->data_type = BCH_DATA_journal; ret = bch2_journal_flush_device_pins(&c->journal, -1); @@ -968,6 +997,7 @@ int bch2_data_job(struct bch_fs *c, if (op.migrate.dev >= c->sb.nr_devices) return -EINVAL; + bch_move_stats_init(stats, "migrate"); stats->data_type = BCH_DATA_journal; ret = bch2_journal_flush_device_pins(&c->journal, op.migrate.dev); @@ -985,6 +1015,7 @@ int bch2_data_job(struct bch_fs *c, ret = bch2_replicas_gc2(c) ?: ret; break; case BCH_DATA_OP_REWRITE_OLD_NODES: + bch_move_stats_init(stats, "rewrite_old_nodes"); ret = bch2_scan_old_btree_nodes(c, stats); break; default: diff --git a/fs/bcachefs/move.h b/fs/bcachefs/move.h index 99d6acb108806..901d8f8759465 100644 --- a/fs/bcachefs/move.h +++ b/fs/bcachefs/move.h @@ -67,4 +67,8 @@ int bch2_data_job(struct bch_fs *, struct bch_move_stats *, struct bch_ioctl_data); +inline void bch_move_stats_init(struct bch_move_stats *stats, + char *name); + + #endif /* _BCACHEFS_MOVE_H */ diff --git a/fs/bcachefs/move_types.h b/fs/bcachefs/move_types.h index fc0de165af9fe..9df6d18137a5e 100644 --- a/fs/bcachefs/move_types.h +++ b/fs/bcachefs/move_types.h @@ -6,6 +6,8 @@ struct bch_move_stats { enum bch_data_type data_type; enum btree_id btree_id; struct bpos pos; + struct list_head list; + char name[32]; atomic64_t keys_moved; atomic64_t keys_raced; diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c index 651381a5ccc5f..b05dcbbd1a476 100644 --- a/fs/bcachefs/movinggc.c +++ b/fs/bcachefs/movinggc.c @@ -147,7 +147,8 @@ static int bch2_copygc(struct bch_fs *c) size_t b, heap_size = 0; int ret; - memset(&move_stats, 0, sizeof(move_stats)); + bch_move_stats_init(&move_stats, "copygc"); + /* * Find buckets with lowest sector counts, skipping completely * empty buckets, by building a maxheap sorted by sector count, diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c index b7e61da0f4d1c..fe0a1dbac199f 100644 --- a/fs/bcachefs/rebalance.c +++ b/fs/bcachefs/rebalance.c @@ -166,6 +166,7 @@ static int bch2_rebalance_thread(void *arg) struct bch_fs_rebalance *r = &c->rebalance; struct io_clock *clock = &c->io_clock[WRITE]; struct rebalance_work w, p; + struct bch_move_stats move_stats; unsigned long start, prev_start; unsigned long prev_run_time, prev_run_cputime; unsigned long cputime, prev_cputime; @@ -179,6 +180,7 @@ static int bch2_rebalance_thread(void *arg) prev_start = jiffies; prev_cputime = curr_cputime(); + bch_move_stats_init(&move_stats, "rebalance"); while (!kthread_wait_freezable(r->enabled)) { cond_resched(); @@ -235,7 +237,7 @@ static int bch2_rebalance_thread(void *arg) prev_cputime = cputime; r->state = REBALANCE_RUNNING; - memset(&r->move_stats, 0, sizeof(r->move_stats)); + memset(&move_stats, 0, sizeof(move_stats)); rebalance_work_reset(c); bch2_move_data(c, @@ -245,7 +247,7 @@ static int bch2_rebalance_thread(void *arg) NULL, /* &r->pd.rate, */ writepoint_ptr(&c->rebalance_write_point), rebalance_pred, NULL, - &r->move_stats); + &move_stats); } return 0; @@ -281,10 +283,7 @@ void bch2_rebalance_work_to_text(struct printbuf *out, struct bch_fs *c) h1); break; case REBALANCE_RUNNING: - pr_buf(out, "running\n" - "pos "); - bch2_bpos_to_text(out, r->move_stats.pos); - pr_buf(out, "\n"); + pr_buf(out, "running\n"); break; } } diff --git a/fs/bcachefs/rebalance_types.h b/fs/bcachefs/rebalance_types.h index 2f62a643c39fb..7462a92e95985 100644 --- a/fs/bcachefs/rebalance_types.h +++ b/fs/bcachefs/rebalance_types.h @@ -19,7 +19,6 @@ struct bch_fs_rebalance { enum rebalance_state state; u64 throttled_until_iotime; unsigned long throttled_until_cputime; - struct bch_move_stats move_stats; unsigned enabled:1; }; diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index afb72648fe541..b02af94f40370 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -1216,7 +1216,9 @@ use_clean: if (!(c->sb.compat & (1ULL << BCH_COMPAT_extents_above_btree_updates_done)) || !(c->sb.compat & (1ULL << BCH_COMPAT_bformat_overflow_done))) { - struct bch_move_stats stats = { 0 }; + struct bch_move_stats stats; + + bch_move_stats_init(&stats, "recovery"); bch_info(c, "scanning for old btree nodes"); ret = bch2_fs_read_write(c); diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 11557a863d3db..1d793e5540845 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -712,6 +712,9 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts) INIT_LIST_HEAD(&c->ec_stripe_new_list); mutex_init(&c->ec_stripe_new_lock); + INIT_LIST_HEAD(&c->data_progress_list); + mutex_init(&c->data_progress_lock); + spin_lock_init(&c->ec_stripes_heap_lock); seqcount_init(&c->gc_pos_lock); diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c index 9b1ffbf96e147..b5ce336f00ca0 100644 --- a/fs/bcachefs/sysfs.c +++ b/fs/bcachefs/sysfs.c @@ -203,6 +203,8 @@ read_attribute(new_stripes); read_attribute(io_timers_read); read_attribute(io_timers_write); +read_attribute(data_op_data_progress); + #ifdef CONFIG_BCACHEFS_TESTS write_attribute(perf_test); #endif /* CONFIG_BCACHEFS_TESTS */ @@ -239,6 +241,37 @@ static size_t bch2_btree_avg_write_size(struct bch_fs *c) return nr ? div64_u64(sectors, nr) : 0; } +static long stats_to_text(struct printbuf *out, struct bch_fs *c, + struct bch_move_stats *stats) +{ + pr_buf(out, "%s: data type %s btree_id %s position: ", + stats->name, + bch2_data_types[stats->data_type], + bch2_btree_ids[stats->btree_id]); + bch2_bpos_to_text(out, stats->pos); + pr_buf(out, "%s", "\n"); + + return 0; +} + +static long data_progress_to_text(struct printbuf *out, struct bch_fs *c) +{ + long ret = 0; + struct bch_move_stats *iter; + + mutex_lock(&c->data_progress_lock); + + if (list_empty(&c->data_progress_list)) + pr_buf(out, "%s", "no progress to report\n"); + else + list_for_each_entry(iter, &c->data_progress_list, list) { + stats_to_text(out, c, iter); + } + + mutex_unlock(&c->data_progress_lock); + return ret; +} + static int fs_alloc_debug_to_text(struct printbuf *out, struct bch_fs *c) { struct bch_fs_usage_online *fs_usage = bch2_fs_usage_read(c); @@ -434,6 +467,11 @@ SHOW(bch2_fs) return out.pos - buf; } + if (attr == &sysfs_data_op_data_progress) { + data_progress_to_text(&out, c); + return out.pos - buf; + } + return 0; } @@ -596,6 +634,8 @@ struct attribute *bch2_fs_internal_files[] = { &sysfs_io_timers_read, &sysfs_io_timers_write, + &sysfs_data_op_data_progress, + &sysfs_internal_uuid, NULL }; -- 2.30.2