bcachefs: Use separate new stripes for copygc and non-copygc
authorKent Overstreet <kent.overstreet@gmail.com>
Tue, 15 Dec 2020 17:53:30 +0000 (12:53 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:50 +0000 (17:08 -0400)
Allocations for copygc have to be kept separate from everything else,
so that copygc doesn't get starved.

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

index 1689e22..df9f022 100644 (file)
@@ -474,7 +474,9 @@ bucket_alloc_from_stripe(struct bch_fs *c,
        if (ec_open_bucket(c, ptrs))
                return 0;
 
-       h = bch2_ec_stripe_head_get(c, target, 0, nr_replicas - 1, cl);
+       h = bch2_ec_stripe_head_get(c, target, 0, nr_replicas - 1,
+                                   wp == &c->copygc_write_point,
+                                   cl);
        if (IS_ERR(h))
                return -PTR_ERR(h);
        if (!h)
index a510ca9..0cfb026 100644 (file)
@@ -87,7 +87,6 @@ struct write_point {
        u64                     last_used;
        unsigned long           write_point;
        enum bch_data_type      type;
-       bool                    is_ec;
 
        /* calculated based on how many pointers we're actually going to use: */
        unsigned                sectors_free;
index f165947..09de327 100644 (file)
@@ -1157,7 +1157,8 @@ static int ec_new_stripe_alloc(struct bch_fs *c, struct ec_stripe_head *h)
 
 static struct ec_stripe_head *
 ec_new_stripe_head_alloc(struct bch_fs *c, unsigned target,
-                        unsigned algo, unsigned redundancy)
+                        unsigned algo, unsigned redundancy,
+                        bool copygc)
 {
        struct ec_stripe_head *h;
        struct bch_dev *ca;
@@ -1173,6 +1174,7 @@ ec_new_stripe_head_alloc(struct bch_fs *c, unsigned target,
        h->target       = target;
        h->algo         = algo;
        h->redundancy   = redundancy;
+       h->copygc       = copygc;
 
        rcu_read_lock();
        h->devs = target_rw_devs(c, BCH_DATA_user, target);
@@ -1204,9 +1206,10 @@ void bch2_ec_stripe_head_put(struct bch_fs *c, struct ec_stripe_head *h)
 }
 
 struct ec_stripe_head *__bch2_ec_stripe_head_get(struct bch_fs *c,
-                                              unsigned target,
-                                              unsigned algo,
-                                              unsigned redundancy)
+                                                unsigned target,
+                                                unsigned algo,
+                                                unsigned redundancy,
+                                                bool copygc)
 {
        struct ec_stripe_head *h;
 
@@ -1217,12 +1220,13 @@ struct ec_stripe_head *__bch2_ec_stripe_head_get(struct bch_fs *c,
        list_for_each_entry(h, &c->ec_stripe_head_list, list)
                if (h->target           == target &&
                    h->algo             == algo &&
-                   h->redundancy       == redundancy) {
+                   h->redundancy       == redundancy &&
+                   h->copygc           == copygc) {
                        mutex_lock(&h->lock);
                        goto found;
                }
 
-       h = ec_new_stripe_head_alloc(c, target, algo, redundancy);
+       h = ec_new_stripe_head_alloc(c, target, algo, redundancy, copygc);
 found:
        mutex_unlock(&c->ec_stripe_head_lock);
        return h;
@@ -1267,7 +1271,9 @@ new_stripe_alloc_buckets(struct bch_fs *c, struct ec_stripe_head *h,
                                            h->redundancy,
                                            &nr_have,
                                            &have_cache,
-                                           RESERVE_NONE,
+                                           h->copygc
+                                           ? RESERVE_MOVINGGC
+                                           : RESERVE_NONE,
                                            0,
                                            cl);
                if (ret)
@@ -1283,7 +1289,9 @@ new_stripe_alloc_buckets(struct bch_fs *c, struct ec_stripe_head *h,
                                            nr_data,
                                            &nr_have,
                                            &have_cache,
-                                           RESERVE_NONE,
+                                           h->copygc
+                                           ? RESERVE_MOVINGGC
+                                           : RESERVE_NONE,
                                            0,
                                            cl);
                if (ret)
@@ -1352,6 +1360,7 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *c,
                                               unsigned target,
                                               unsigned algo,
                                               unsigned redundancy,
+                                              bool copygc,
                                               struct closure *cl)
 {
        struct ec_stripe_head *h;
@@ -1360,7 +1369,7 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *c,
        s64 idx;
        int ret;
 
-       h = __bch2_ec_stripe_head_get(c, target, algo, redundancy);
+       h = __bch2_ec_stripe_head_get(c, target, algo, redundancy, copygc);
        if (!h) {
                bch_err(c, "no stripe head");
                return NULL;
index 3f1999b..97a263c 100644 (file)
@@ -122,6 +122,7 @@ struct ec_stripe_head {
        unsigned                target;
        unsigned                algo;
        unsigned                redundancy;
+       bool                    copygc;
 
        struct bch_devs_mask    devs;
        unsigned                nr_active_devs;
@@ -147,7 +148,7 @@ int bch2_ec_stripe_new_alloc(struct bch_fs *, struct ec_stripe_head *);
 
 void bch2_ec_stripe_head_put(struct bch_fs *, struct ec_stripe_head *);
 struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *,
-                       unsigned, unsigned, unsigned, struct closure *);
+                       unsigned, unsigned, unsigned, bool, struct closure *);
 
 void bch2_stripes_heap_update(struct bch_fs *, struct stripe *, size_t);
 void bch2_stripes_heap_del(struct bch_fs *, struct stripe *, size_t);