]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bcachefs: bch2_time_stats_init_no_pcpu()
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 25 Mar 2025 14:52:00 +0000 (10:52 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 29 Mar 2025 02:31:47 +0000 (22:31 -0400)
Add a mode to disable automatic switching to percpu mode, useful when a
time_stats will only be used by one thread and we don't want to have to
flush the percpu buffers.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/time_stats.c
fs/bcachefs/time_stats.h

index 3fe82757f93aacc83c4989b6dfc0b8b4af23acd2..2c34fe4be91202d86c4dd477ae75d3801c0b55fe 100644 (file)
@@ -10,6 +10,9 @@
 #include "eytzinger.h"
 #include "time_stats.h"
 
+/* disable automatic switching to percpu mode */
+#define TIME_STATS_NONPCPU     ((unsigned long) 1)
+
 static const struct time_unit time_units[] = {
        { "ns",         1                },
        { "us",         NSEC_PER_USEC    },
@@ -123,11 +126,12 @@ void __bch2_time_stats_update(struct bch2_time_stats *stats, u64 start, u64 end)
 {
        unsigned long flags;
 
-       if (!stats->buffer) {
+       if ((unsigned long) stats->buffer <= TIME_STATS_NONPCPU) {
                spin_lock_irqsave(&stats->lock, flags);
                time_stats_update_one(stats, start, end);
 
-               if (mean_and_variance_weighted_get_mean(stats->freq_stats_weighted, TIME_STATS_MV_WEIGHT) < 32 &&
+               if (!stats->buffer &&
+                   mean_and_variance_weighted_get_mean(stats->freq_stats_weighted, TIME_STATS_MV_WEIGHT) < 32 &&
                    stats->duration_stats.n > 1024)
                        stats->buffer =
                                alloc_percpu_gfp(struct time_stat_buffer,
@@ -157,7 +161,7 @@ void bch2_time_stats_reset(struct bch2_time_stats *stats)
        unsigned offset = offsetof(struct bch2_time_stats, min_duration);
        memset((void *) stats + offset, 0, sizeof(*stats) - offset);
 
-       if (stats->buffer) {
+       if ((unsigned long) stats->buffer > TIME_STATS_NONPCPU) {
                int cpu;
                for_each_possible_cpu(cpu)
                        per_cpu_ptr(stats->buffer, cpu)->nr = 0;
@@ -167,7 +171,9 @@ void bch2_time_stats_reset(struct bch2_time_stats *stats)
 
 void bch2_time_stats_exit(struct bch2_time_stats *stats)
 {
-       free_percpu(stats->buffer);
+       if ((unsigned long) stats->buffer > TIME_STATS_NONPCPU)
+               free_percpu(stats->buffer);
+       stats->buffer = NULL;
 }
 
 void bch2_time_stats_init(struct bch2_time_stats *stats)
@@ -177,3 +183,9 @@ void bch2_time_stats_init(struct bch2_time_stats *stats)
        stats->min_freq = U64_MAX;
        spin_lock_init(&stats->lock);
 }
+
+void bch2_time_stats_init_no_pcpu(struct bch2_time_stats *stats)
+{
+       bch2_time_stats_init(stats);
+       stats->buffer = (struct time_stat_buffer __percpu *) TIME_STATS_NONPCPU;
+}
index dc6493f7bbabc69955c44481d46a58a3a5bc1e1a..eddb0985bab4bc5e71f63aafbd13378d8fb4e6ef 100644 (file)
@@ -145,6 +145,7 @@ static inline bool track_event_change(struct bch2_time_stats *stats, bool v)
 void bch2_time_stats_reset(struct bch2_time_stats *);
 void bch2_time_stats_exit(struct bch2_time_stats *);
 void bch2_time_stats_init(struct bch2_time_stats *);
+void bch2_time_stats_init_no_pcpu(struct bch2_time_stats *);
 
 static inline void bch2_time_stats_quantiles_exit(struct bch2_time_stats_quantiles *statq)
 {