Skip to content

Commit 273960b

Browse files
Darrick J. WongKent Overstreet
authored andcommitted
bcachefs: time_stats: split stats-with-quantiles into a separate structure
Currently, struct time_stats has the optional ability to quantize the information that it collects. This is /probably/ useful for callers who want to see quantized information, but it more than doubles the size of the structure from 224 bytes to 464. For users who don't care about that (e.g. upcoming xfs patches) and want to avoid wasting 240 bytes per counter, split the two into separate pieces. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 4b4f087 commit 273960b

File tree

7 files changed

+41
-15
lines changed

7 files changed

+41
-15
lines changed

fs/bcachefs/bcachefs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ struct bch_dev {
598598

599599
/* The rest of this all shows up in sysfs */
600600
atomic64_t cur_latency[2];
601-
struct bch2_time_stats io_latency[2];
601+
struct bch2_time_stats_quantiles io_latency[2];
602602

603603
#define CONGESTED_MAX 1024
604604
atomic_t congested;

fs/bcachefs/io_write.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void bch2_latency_acct(struct bch_dev *ca, u64 submit_time, int rw)
8888

8989
bch2_congested_acct(ca, io_latency, now, rw);
9090

91-
__bch2_time_stats_update(&ca->io_latency[rw], submit_time, now);
91+
__bch2_time_stats_update(&ca->io_latency[rw].stats, submit_time, now);
9292
}
9393

9494
#endif

fs/bcachefs/super.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,8 +1189,8 @@ static void bch2_dev_free(struct bch_dev *ca)
11891189
bch2_dev_buckets_free(ca);
11901190
free_page((unsigned long) ca->sb_read_scratch);
11911191

1192-
bch2_time_stats_exit(&ca->io_latency[WRITE]);
1193-
bch2_time_stats_exit(&ca->io_latency[READ]);
1192+
bch2_time_stats_quantiles_exit(&ca->io_latency[WRITE]);
1193+
bch2_time_stats_quantiles_exit(&ca->io_latency[READ]);
11941194

11951195
percpu_ref_exit(&ca->io_ref);
11961196
percpu_ref_exit(&ca->ref);
@@ -1281,8 +1281,8 @@ static struct bch_dev *__bch2_dev_alloc(struct bch_fs *c,
12811281

12821282
INIT_WORK(&ca->io_error_work, bch2_io_error_work);
12831283

1284-
bch2_time_stats_init(&ca->io_latency[READ]);
1285-
bch2_time_stats_init(&ca->io_latency[WRITE]);
1284+
bch2_time_stats_quantiles_init(&ca->io_latency[READ]);
1285+
bch2_time_stats_quantiles_init(&ca->io_latency[WRITE]);
12861286

12871287
ca->mi = bch2_mi_to_cpu(member);
12881288

fs/bcachefs/sysfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -930,10 +930,10 @@ SHOW(bch2_dev)
930930
sysfs_print(io_latency_write, atomic64_read(&ca->cur_latency[WRITE]));
931931

932932
if (attr == &sysfs_io_latency_stats_read)
933-
bch2_time_stats_to_text(out, &ca->io_latency[READ]);
933+
bch2_time_stats_to_text(out, &ca->io_latency[READ].stats);
934934

935935
if (attr == &sysfs_io_latency_stats_write)
936-
bch2_time_stats_to_text(out, &ca->io_latency[WRITE]);
936+
bch2_time_stats_to_text(out, &ca->io_latency[WRITE].stats);
937937

938938
sysfs_printf(congested, "%u%%",
939939
clamp(atomic_read(&ca->congested), 0, CONGESTED_MAX)

fs/bcachefs/time_stats.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ static inline void time_stats_update_one(struct bch2_time_stats *stats,
7373
bool initted = stats->last_event != 0;
7474

7575
if (time_after64(end, start)) {
76+
struct quantiles *quantiles = time_stats_to_quantiles(stats);
77+
7678
duration = end - start;
7779
mean_and_variance_update(&stats->duration_stats, duration);
7880
mean_and_variance_weighted_update(&stats->duration_stats_weighted,
@@ -81,8 +83,8 @@ static inline void time_stats_update_one(struct bch2_time_stats *stats,
8183
stats->min_duration = min(stats->min_duration, duration);
8284
stats->total_duration += duration;
8385

84-
if (stats->quantiles_enabled)
85-
quantiles_update(&stats->quantiles, duration);
86+
if (quantiles)
87+
quantiles_update(quantiles, duration);
8688
}
8789

8890
if (stats->last_event && time_after64(end, stats->last_event)) {

fs/bcachefs/time_stats.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <linux/sched/clock.h>
2828
#include <linux/spinlock_types.h>
29+
#include <linux/string.h>
2930

3031
#include "mean_and_variance.h"
3132

@@ -68,7 +69,7 @@ struct time_stat_buffer {
6869

6970
struct bch2_time_stats {
7071
spinlock_t lock;
71-
bool quantiles_enabled;
72+
bool have_quantiles;
7273
/* all fields are in nanoseconds */
7374
u64 min_duration;
7475
u64 max_duration;
@@ -77,7 +78,6 @@ struct bch2_time_stats {
7778
u64 min_freq;
7879
u64 last_event;
7980
u64 last_event_start;
80-
struct quantiles quantiles;
8181

8282
struct mean_and_variance duration_stats;
8383
struct mean_and_variance freq_stats;
@@ -90,6 +90,18 @@ struct bch2_time_stats {
9090
struct time_stat_buffer __percpu *buffer;
9191
};
9292

93+
struct bch2_time_stats_quantiles {
94+
struct bch2_time_stats stats;
95+
struct quantiles quantiles;
96+
};
97+
98+
static inline struct quantiles *time_stats_to_quantiles(struct bch2_time_stats *stats)
99+
{
100+
return stats->have_quantiles
101+
? &container_of(stats, struct bch2_time_stats_quantiles, stats)->quantiles
102+
: NULL;
103+
}
104+
93105
void __bch2_time_stats_clear_buffer(struct bch2_time_stats *, struct time_stat_buffer *);
94106
void __bch2_time_stats_update(struct bch2_time_stats *stats, u64, u64);
95107

@@ -133,4 +145,15 @@ static inline bool track_event_change(struct bch2_time_stats *stats, bool v)
133145
void bch2_time_stats_exit(struct bch2_time_stats *);
134146
void bch2_time_stats_init(struct bch2_time_stats *);
135147

148+
static inline void bch2_time_stats_quantiles_exit(struct bch2_time_stats_quantiles *statq)
149+
{
150+
bch2_time_stats_exit(&statq->stats);
151+
}
152+
static inline void bch2_time_stats_quantiles_init(struct bch2_time_stats_quantiles *statq)
153+
{
154+
bch2_time_stats_init(&statq->stats);
155+
statq->stats.have_quantiles = true;
156+
memset(&statq->quantiles, 0, sizeof(statq->quantiles));
157+
}
158+
136159
#endif /* _BCACHEFS_TIME_STATS_H */

fs/bcachefs/util.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ static inline void pr_name_and_units(struct printbuf *out, const char *name, u64
365365

366366
void bch2_time_stats_to_text(struct printbuf *out, struct bch2_time_stats *stats)
367367
{
368+
struct quantiles *quantiles = time_stats_to_quantiles(stats);
368369
s64 f_mean = 0, d_mean = 0;
369370
u64 f_stddev = 0, d_stddev = 0;
370371

@@ -465,17 +466,17 @@ void bch2_time_stats_to_text(struct printbuf *out, struct bch2_time_stats *stats
465466

466467
printbuf_tabstops_reset(out);
467468

468-
if (stats->quantiles_enabled) {
469+
if (quantiles) {
469470
int i = eytzinger0_first(NR_QUANTILES);
470471
const struct time_unit *u =
471-
bch2_pick_time_units(stats->quantiles.entries[i].m);
472+
bch2_pick_time_units(quantiles->entries[i].m);
472473
u64 last_q = 0;
473474

474475
prt_printf(out, "quantiles (%s):\t", u->name);
475476
eytzinger0_for_each(i, NR_QUANTILES) {
476477
bool is_last = eytzinger0_next(i, NR_QUANTILES) == -1;
477478

478-
u64 q = max(stats->quantiles.entries[i].m, last_q);
479+
u64 q = max(quantiles->entries[i].m, last_q);
479480
prt_printf(out, "%llu ", div_u64(q, u->nsecs));
480481
if (is_last)
481482
prt_newline(out);

0 commit comments

Comments
 (0)