diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2025-07-13 09:47:38 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-07-22 12:05:20 -0400 |
commit | 09e8db09049a118e5286ee3ec198d7597d443e92 (patch) | |
tree | 15ae7b856f73bf58a8562abf645c149243807f14 | |
parent | 7a0cf80f8682c2ea77ecbbde812f06c86da40971 (diff) |
bcachefs: Better congestion visibilty in sysfs
/sys/fs/bcachefs/<uuid>/dev-n/congested now prints more info on how we
calculate device congestion.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/io_read.c | 61 | ||||
-rw-r--r-- | fs/bcachefs/io_read.h | 4 | ||||
-rw-r--r-- | fs/bcachefs/sysfs.c | 11 |
3 files changed, 60 insertions, 16 deletions
diff --git a/fs/bcachefs/io_read.c b/fs/bcachefs/io_read.c index 2f458fc88f03..f24c1c3e8f19 100644 --- a/fs/bcachefs/io_read.c +++ b/fs/bcachefs/io_read.c @@ -45,38 +45,73 @@ MODULE_PARM_DESC(poison_extents_on_checksum_error, #ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT +static inline u32 bch2_dev_congested_read(struct bch_dev *ca, u64 now) +{ + s64 congested = atomic_read(&ca->congested); + u64 last = READ_ONCE(ca->congested_last); + if (time_after64(now, last)) + congested -= (now - last) >> 12; + + return clamp(congested, 0LL, CONGESTED_MAX); +} + static bool bch2_target_congested(struct bch_fs *c, u16 target) { const struct bch_devs_mask *devs; unsigned d, nr = 0, total = 0; - u64 now = local_clock(), last; - s64 congested; - struct bch_dev *ca; - - if (!target) - return false; + u64 now = local_clock(); guard(rcu)(); devs = bch2_target_to_mask(c, target) ?: &c->rw_devs[BCH_DATA_user]; for_each_set_bit(d, devs->d, BCH_SB_MEMBERS_MAX) { - ca = rcu_dereference(c->devs[d]); + struct bch_dev *ca = rcu_dereference(c->devs[d]); if (!ca) continue; - congested = atomic_read(&ca->congested); - last = READ_ONCE(ca->congested_last); - if (time_after64(now, last)) - congested -= (now - last) >> 12; - - total += max(congested, 0LL); + total += bch2_dev_congested_read(ca, now); nr++; } return get_random_u32_below(nr * CONGESTED_MAX) < total; } +void bch2_dev_congested_to_text(struct printbuf *out, struct bch_dev *ca) +{ + printbuf_tabstop_push(out, 32); + + prt_printf(out, "current:\t%u%%\n", + bch2_dev_congested_read(ca, local_clock()) * + 100 / CONGESTED_MAX); + + prt_printf(out, "raw:\t%i/%u\n", atomic_read(&ca->congested), CONGESTED_MAX); + + prt_printf(out, "last io over threshold:\t"); + bch2_pr_time_units(out, local_clock() - ca->congested_last); + prt_newline(out); + + prt_printf(out, "read latency threshold:\t"); + bch2_pr_time_units(out, + ca->io_latency[READ].quantiles.entries[QUANTILE_IDX(1)].m << 2); + prt_newline(out); + + prt_printf(out, "median read latency:\t"); + bch2_pr_time_units(out, + ca->io_latency[READ].quantiles.entries[QUANTILE_IDX(7)].m); + prt_newline(out); + + prt_printf(out, "write latency threshold:\t"); + bch2_pr_time_units(out, + ca->io_latency[WRITE].quantiles.entries[QUANTILE_IDX(1)].m << 3); + prt_newline(out); + + prt_printf(out, "median write latency:\t"); + bch2_pr_time_units(out, + ca->io_latency[WRITE].quantiles.entries[QUANTILE_IDX(7)].m); + prt_newline(out); +} + #else static bool bch2_target_congested(struct bch_fs *c, u16 target) diff --git a/fs/bcachefs/io_read.h b/fs/bcachefs/io_read.h index 1afd19402682..8fef4e47f16d 100644 --- a/fs/bcachefs/io_read.h +++ b/fs/bcachefs/io_read.h @@ -7,6 +7,10 @@ #include "extents_types.h" #include "reflink.h" +#ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT +void bch2_dev_congested_to_text(struct printbuf *, struct bch_dev *); +#endif + struct bch_read_bio { struct bch_fs *c; u64 start_time; diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c index 05848375cea2..ac8d03d3c835 100644 --- a/fs/bcachefs/sysfs.c +++ b/fs/bcachefs/sysfs.c @@ -170,7 +170,9 @@ read_attribute(io_latency_read); read_attribute(io_latency_write); read_attribute(io_latency_stats_read); read_attribute(io_latency_stats_write); +#ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT read_attribute(congested); +#endif read_attribute(btree_write_stats); @@ -830,9 +832,10 @@ SHOW(bch2_dev) if (attr == &sysfs_io_latency_stats_write) bch2_time_stats_to_text(out, &ca->io_latency[WRITE].stats); - sysfs_printf(congested, "%u%%", - clamp(atomic_read(&ca->congested), 0, CONGESTED_MAX) - * 100 / CONGESTED_MAX); +#ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT + if (attr == &sysfs_congested) + bch2_dev_congested_to_text(out, ca); +#endif if (attr == &sysfs_alloc_debug) bch2_dev_alloc_debug_to_text(out, ca); @@ -900,7 +903,9 @@ struct attribute *bch2_dev_files[] = { &sysfs_io_latency_write, &sysfs_io_latency_stats_read, &sysfs_io_latency_stats_write, +#ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT &sysfs_congested, +#endif /* debug: */ &sysfs_alloc_debug, |