diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-06-27 15:58:48 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-06-27 15:58:48 -0400 |
commit | bad0c8c50758b4447d529f61017c1a8c85976a3e (patch) | |
tree | c27806cdcab52e6697163daeca7b9e903fcd6f64 /libbcachefs/alloc_background.c | |
parent | 64ddfc9fc5628f27cdc1399a283452196a7e2dcc (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.c | 106 |
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, + §ors)); 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) |