summaryrefslogtreecommitdiff
path: root/libbcachefs/alloc_background.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-06-27 15:58:48 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2022-06-27 15:58:48 -0400
commitbad0c8c50758b4447d529f61017c1a8c85976a3e (patch)
treec27806cdcab52e6697163daeca7b9e903fcd6f64 /libbcachefs/alloc_background.c
parent64ddfc9fc5628f27cdc1399a283452196a7e2dcc (diff)
Update bcachefs sources to 95ff72a6c1 fixup! mm: Centralize & improve oom reporting in show_mem.c
Diffstat (limited to 'libbcachefs/alloc_background.c')
-rw-r--r--libbcachefs/alloc_background.c106
1 files changed, 65 insertions, 41 deletions
diff --git a/libbcachefs/alloc_background.c b/libbcachefs/alloc_background.c
index 359cb23..7385671 100644
--- a/libbcachefs/alloc_background.c
+++ b/libbcachefs/alloc_background.c
@@ -685,21 +685,23 @@ int bch2_trans_mark_alloc(struct btree_trans *trans,
}
static int bch2_check_alloc_key(struct btree_trans *trans,
- struct btree_iter *alloc_iter)
+ struct btree_iter *alloc_iter,
+ struct btree_iter *discard_iter,
+ struct btree_iter *freespace_iter)
{
struct bch_fs *c = trans->c;
struct bch_dev *ca;
- struct btree_iter discard_iter, freespace_iter;
struct bch_alloc_v4 a;
unsigned discard_key_type, freespace_key_type;
struct bkey_s_c alloc_k, k;
struct printbuf buf = PRINTBUF;
- struct printbuf buf2 = PRINTBUF;
int ret;
- alloc_k = bch2_btree_iter_peek(alloc_iter);
+ alloc_k = bch2_dev_bucket_exists(c, alloc_iter->pos)
+ ? bch2_btree_iter_peek_slot(alloc_iter)
+ : bch2_btree_iter_peek(alloc_iter);
if (!alloc_k.k)
- return 0;
+ return 1;
ret = bkey_err(alloc_k);
if (ret)
@@ -721,12 +723,10 @@ static int bch2_check_alloc_key(struct btree_trans *trans,
freespace_key_type = a.data_type == BCH_DATA_free
? KEY_TYPE_set : 0;
- bch2_trans_iter_init(trans, &discard_iter, BTREE_ID_need_discard,
- alloc_k.k->p, 0);
- bch2_trans_iter_init(trans, &freespace_iter, BTREE_ID_freespace,
- alloc_freespace_pos(alloc_k.k->p, a), 0);
+ bch2_btree_iter_set_pos(discard_iter, alloc_k.k->p);
+ bch2_btree_iter_set_pos(freespace_iter, alloc_freespace_pos(alloc_k.k->p, a));
- k = bch2_btree_iter_peek_slot(&discard_iter);
+ k = bch2_btree_iter_peek_slot(discard_iter);
ret = bkey_err(k);
if (ret)
goto err;
@@ -746,14 +746,14 @@ static int bch2_check_alloc_key(struct btree_trans *trans,
bkey_init(&update->k);
update->k.type = discard_key_type;
- update->k.p = discard_iter.pos;
+ update->k.p = discard_iter->pos;
- ret = bch2_trans_update(trans, &discard_iter, update, 0);
+ ret = bch2_trans_update(trans, discard_iter, update, 0);
if (ret)
goto err;
}
- k = bch2_btree_iter_peek_slot(&freespace_iter);
+ k = bch2_btree_iter_peek_slot(freespace_iter);
ret = bkey_err(k);
if (ret)
goto err;
@@ -774,18 +774,15 @@ static int bch2_check_alloc_key(struct btree_trans *trans,
bkey_init(&update->k);
update->k.type = freespace_key_type;
- update->k.p = freespace_iter.pos;
+ update->k.p = freespace_iter->pos;
bch2_key_resize(&update->k, 1);
- ret = bch2_trans_update(trans, &freespace_iter, update, 0);
+ ret = bch2_trans_update(trans, freespace_iter, update, 0);
if (ret)
goto err;
}
err:
fsck_err:
- bch2_trans_iter_exit(trans, &freespace_iter);
- bch2_trans_iter_exit(trans, &discard_iter);
- printbuf_exit(&buf2);
printbuf_exit(&buf);
return ret;
}
@@ -855,48 +852,64 @@ delete:
int bch2_check_alloc_info(struct bch_fs *c)
{
struct btree_trans trans;
- struct btree_iter iter;
- struct bkey_s_c k;
+ struct btree_iter iter, discard_iter, freespace_iter;
int ret = 0;
bch2_trans_init(&trans, c, 0, 0);
- for_each_btree_key(&trans, iter, BTREE_ID_alloc, POS_MIN,
- BTREE_ITER_PREFETCH, k, ret) {
- ret = __bch2_trans_do(&trans, NULL, NULL, 0,
- bch2_check_alloc_key(&trans, &iter));
+ bch2_trans_iter_init(&trans, &iter, BTREE_ID_alloc, POS_MIN,
+ BTREE_ITER_PREFETCH);
+ bch2_trans_iter_init(&trans, &discard_iter, BTREE_ID_need_discard, POS_MIN,
+ BTREE_ITER_PREFETCH);
+ bch2_trans_iter_init(&trans, &freespace_iter, BTREE_ID_freespace, POS_MIN,
+ BTREE_ITER_PREFETCH);
+ while (1) {
+ ret = __bch2_trans_do(&trans, NULL, NULL,
+ BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_LAZY_RW,
+ bch2_check_alloc_key(&trans, &iter,
+ &discard_iter,
+ &freespace_iter));
if (ret)
break;
+
+ bch2_btree_iter_advance(&iter);
}
+ bch2_trans_iter_exit(&trans, &freespace_iter);
+ bch2_trans_iter_exit(&trans, &discard_iter);
bch2_trans_iter_exit(&trans, &iter);
- if (ret)
+ if (ret < 0)
goto err;
bch2_trans_iter_init(&trans, &iter, BTREE_ID_need_discard, POS_MIN,
BTREE_ITER_PREFETCH);
while (1) {
- ret = __bch2_trans_do(&trans, NULL, NULL, 0,
+ ret = __bch2_trans_do(&trans, NULL, NULL,
+ BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_LAZY_RW,
bch2_check_discard_freespace_key(&trans, &iter));
if (ret)
break;
- bch2_btree_iter_set_pos(&iter, bpos_nosnap_successor(iter.pos));
+ bch2_btree_iter_advance(&iter);
}
bch2_trans_iter_exit(&trans, &iter);
- if (ret)
+ if (ret < 0)
goto err;
bch2_trans_iter_init(&trans, &iter, BTREE_ID_freespace, POS_MIN,
BTREE_ITER_PREFETCH);
while (1) {
- ret = __bch2_trans_do(&trans, NULL, NULL, 0,
+ ret = __bch2_trans_do(&trans, NULL, NULL,
+ BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_LAZY_RW,
bch2_check_discard_freespace_key(&trans, &iter));
if (ret)
break;
- bch2_btree_iter_set_pos(&iter, bpos_nosnap_successor(iter.pos));
+ bch2_btree_iter_advance(&iter);
}
bch2_trans_iter_exit(&trans, &iter);
err:
@@ -1151,12 +1164,13 @@ static void bch2_do_discards_work(struct work_struct *work)
void bch2_do_discards(struct bch_fs *c)
{
- if (percpu_ref_tryget(&c->writes) &&
+ if (percpu_ref_tryget_live(&c->writes) &&
!queue_work(system_long_wq, &c->discard_work))
percpu_ref_put(&c->writes);
}
-static int invalidate_one_bucket(struct btree_trans *trans, struct bch_dev *ca)
+static int invalidate_one_bucket(struct btree_trans *trans, struct bch_dev *ca,
+ struct bpos *bucket_pos, unsigned *cached_sectors)
{
struct bch_fs *c = trans->c;
struct btree_iter lru_iter, alloc_iter = { NULL };
@@ -1174,8 +1188,10 @@ next_lru:
if (ret)
goto out;
- if (!k.k || k.k->p.inode != ca->dev_idx)
+ if (!k.k || k.k->p.inode != ca->dev_idx) {
+ ret = 1;
goto out;
+ }
if (k.k->type != KEY_TYPE_lru) {
prt_printf(&buf, "non lru key in lru btree:\n ");
@@ -1195,8 +1211,9 @@ next_lru:
idx = k.k->p.offset;
bucket = le64_to_cpu(bkey_s_c_to_lru(k).v->idx);
- a = bch2_trans_start_alloc_update(trans, &alloc_iter,
- POS(ca->dev_idx, bucket));
+ *bucket_pos = POS(ca->dev_idx, bucket);
+
+ a = bch2_trans_start_alloc_update(trans, &alloc_iter, *bucket_pos);
ret = PTR_ERR_OR_ZERO(a);
if (ret)
goto out;
@@ -1218,6 +1235,11 @@ next_lru:
}
}
+ if (!a->v.cached_sectors)
+ bch_err(c, "invalidating empty bucket, confused");
+
+ *cached_sectors = a->v.cached_sectors;
+
SET_BCH_ALLOC_V4_NEED_INC_GEN(&a->v, false);
a->v.gen++;
a->v.data_type = 0;
@@ -1230,8 +1252,6 @@ next_lru:
BTREE_TRIGGER_BUCKET_INVALIDATE);
if (ret)
goto out;
-
- trace_invalidate_bucket(c, a->k.p.inode, a->k.p.offset);
out:
bch2_trans_iter_exit(trans, &alloc_iter);
bch2_trans_iter_exit(trans, &lru_iter);
@@ -1244,7 +1264,8 @@ static void bch2_do_invalidates_work(struct work_struct *work)
struct bch_fs *c = container_of(work, struct bch_fs, invalidate_work);
struct bch_dev *ca;
struct btree_trans trans;
- unsigned i;
+ struct bpos bucket;
+ unsigned i, sectors;
int ret = 0;
bch2_trans_init(&trans, c, 0, 0);
@@ -1257,10 +1278,12 @@ static void bch2_do_invalidates_work(struct work_struct *work)
ret = __bch2_trans_do(&trans, NULL, NULL,
BTREE_INSERT_USE_RESERVE|
BTREE_INSERT_NOFAIL,
- invalidate_one_bucket(&trans, ca));
+ invalidate_one_bucket(&trans, ca, &bucket,
+ &sectors));
if (ret)
break;
+ trace_invalidate_bucket(c, bucket.inode, bucket.offset, sectors);
this_cpu_inc(c->counters[BCH_COUNTER_bucket_invalidate]);
}
}
@@ -1271,8 +1294,9 @@ static void bch2_do_invalidates_work(struct work_struct *work)
void bch2_do_invalidates(struct bch_fs *c)
{
- if (percpu_ref_tryget(&c->writes))
- queue_work(system_long_wq, &c->invalidate_work);
+ if (percpu_ref_tryget_live(&c->writes) &&
+ !queue_work(system_long_wq, &c->invalidate_work))
+ percpu_ref_put(&c->writes);
}
static int bucket_freespace_init(struct btree_trans *trans, struct btree_iter *iter)