bcachefs: Use separate new stripes for copygc and non-copygc

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>
This commit is contained in:
Kent Overstreet 2020-12-15 12:53:30 -05:00 committed by Kent Overstreet
parent 2c40a2403e
commit 8deed5f4e5
4 changed files with 23 additions and 12 deletions

View 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)

View 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;

View 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;

View 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);