]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: bch2_copygc_dev_wait_amount()
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 8 May 2025 18:24:12 +0000 (14:24 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 22 May 2025 00:14:50 +0000 (20:14 -0400)
Factor out the per-device calculations, for better introspection.

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

index b50846da7ae40988e5f29e5ab10fc27d627d6b44..828cf94217ddc73c204651d08f80c610560d3872 100644 (file)
@@ -465,7 +465,7 @@ static noinline void trace_bucket_alloc2(struct bch_fs *c,
        prt_printf(&buf, "blocking\t%u\n",      cl != NULL);
        prt_printf(&buf, "free\t%llu\n",        req->usage.buckets[BCH_DATA_free]);
        prt_printf(&buf, "avail\t%llu\n",       dev_buckets_free(req->ca, req->usage, req->watermark));
-       prt_printf(&buf, "copygc_wait\t%lu/%lli\n",
+       prt_printf(&buf, "copygc_wait\t%llu/%lli\n",
                   bch2_copygc_wait_amount(c),
                   c->copygc_wait - atomic64_read(&c->io_clock[WRITE].now));
        prt_printf(&buf, "seen\t%llu\n",        req->counters.buckets_seen);
index e97e87ebe312bef0cd5f775c79b8108d49bc51e9..6e5680a3a97ccfac03a51249dc9311f8cccb4693 100644 (file)
@@ -261,6 +261,25 @@ err:
        return ret;
 }
 
+static u64 bch2_copygc_dev_wait_amount(struct bch_dev *ca)
+{
+       struct bch_dev_usage_full usage_full = bch2_dev_usage_full_read(ca);
+       struct bch_dev_usage usage;
+
+       for (unsigned i = 0; i < BCH_DATA_NR; i++)
+               usage.buckets[i] = usage_full.d[i].buckets;
+
+       s64 fragmented_allowed = ((__dev_buckets_available(ca, usage, BCH_WATERMARK_stripe) *
+                                  ca->mi.bucket_size) >> 1);
+       s64 fragmented = 0;
+
+       for (unsigned i = 0; i < BCH_DATA_NR; i++)
+               if (data_type_movable(i))
+                       fragmented += usage_full.d[i].fragmented;
+
+       return max(0LL, fragmented_allowed - fragmented);
+}
+
 /*
  * Copygc runs when the amount of fragmented data is above some arbitrary
  * threshold:
@@ -275,28 +294,13 @@ err:
  * often and continually reduce the amount of fragmented space as the device
  * fills up. So, we increase the threshold by half the current free space.
  */
-unsigned long bch2_copygc_wait_amount(struct bch_fs *c)
+u64 bch2_copygc_wait_amount(struct bch_fs *c)
 {
-       s64 wait = S64_MAX, fragmented_allowed, fragmented;
+       u64 wait = U64_MAX;
 
        rcu_read_lock();
-       for_each_rw_member_rcu(c, ca) {
-               struct bch_dev_usage_full usage_full = bch2_dev_usage_full_read(ca);
-               struct bch_dev_usage usage;
-
-               for (unsigned i = 0; i < BCH_DATA_NR; i++)
-                       usage.buckets[i] = usage_full.d[i].buckets;
-
-               fragmented_allowed = ((__dev_buckets_available(ca, usage, BCH_WATERMARK_stripe) *
-                                      ca->mi.bucket_size) >> 1);
-               fragmented = 0;
-
-               for (unsigned i = 0; i < BCH_DATA_NR; i++)
-                       if (data_type_movable(i))
-                               fragmented += usage_full.d[i].fragmented;
-
-               wait = min(wait, max(0LL, fragmented_allowed - fragmented));
-       }
+       for_each_rw_member_rcu(c, ca)
+               wait = min(wait, bch2_copygc_dev_wait_amount(ca));
        rcu_read_unlock();
 
        return wait;
@@ -320,14 +324,22 @@ void bch2_copygc_wait_to_text(struct printbuf *out, struct bch_fs *c)
                                        c->copygc_wait_at) << 9);
        prt_newline(out);
 
-       prt_printf(out, "Currently calculated wait:\t");
-       prt_human_readable_u64(out, bch2_copygc_wait_amount(c));
-       prt_newline(out);
+       bch2_printbuf_make_room(out, 4096);
 
        rcu_read_lock();
+       out->atomic++;
+
+       prt_printf(out, "Currently calculated wait:\n");
+       for_each_rw_member_rcu(c, ca) {
+               prt_printf(out, "  %s:\t", ca->name);
+               prt_human_readable_u64(out, bch2_copygc_dev_wait_amount(ca));
+               prt_newline(out);
+       }
+
        struct task_struct *t = rcu_dereference(c->copygc_thread);
        if (t)
                get_task_struct(t);
+       --out->atomic;
        rcu_read_unlock();
 
        if (t) {
index d1885cf67a457484b4d06fdd47af4ce7b9487341..b9683d22bab08e2bcf86f1e2fef872f8e00be5e0 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef _BCACHEFS_MOVINGGC_H
 #define _BCACHEFS_MOVINGGC_H
 
-unsigned long bch2_copygc_wait_amount(struct bch_fs *);
+u64 bch2_copygc_wait_amount(struct bch_fs *);
 void bch2_copygc_wait_to_text(struct printbuf *, struct bch_fs *);
 
 static inline void bch2_copygc_wakeup(struct bch_fs *c)