mirror of
https://github.com/torvalds/linux.git
synced 2026-05-05 23:05:25 -04:00
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 <bholman.devel@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
committed by
Kent Overstreet
parent
fd0bd123d5
commit
8dd6ed9451
@@ -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];
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user