diff options
Diffstat (limited to 'libbcachefs/tier.c')
-rw-r--r-- | libbcachefs/tier.c | 126 |
1 files changed, 26 insertions, 100 deletions
diff --git a/libbcachefs/tier.c b/libbcachefs/tier.c index cbfcfccc..2e29f741 100644 --- a/libbcachefs/tier.c +++ b/libbcachefs/tier.c @@ -15,105 +15,23 @@ #include <linux/kthread.h> #include <trace/events/bcachefs.h> -struct tiering_state { - struct bch_tier *tier; - unsigned sectors; - unsigned stripe_size; - unsigned dev_idx; - struct bch_dev *ca; -}; - -static bool tiering_pred(struct bch_fs *c, - struct bch_tier *tier, - struct bkey_s_c k) +static bool tiering_pred(void *arg, struct bkey_s_c_extent e) { - if (bkey_extent_is_data(k.k)) { - struct bkey_s_c_extent e = bkey_s_c_to_extent(k); - const struct bch_extent_ptr *ptr; - unsigned replicas = 0; - - /* Make sure we have room to add a new pointer: */ - if (bkey_val_u64s(e.k) + BKEY_EXTENT_PTR_U64s_MAX > - BKEY_EXTENT_VAL_U64s_MAX) - return false; - - extent_for_each_ptr(e, ptr) - if (c->devs[ptr->dev]->mi.tier >= tier->idx) - replicas++; - - return replicas < c->opts.data_replicas; - } - - return false; -} - -static int issue_tiering_move(struct bch_fs *c, - struct bch_tier *tier, - struct moving_context *ctxt, - struct bkey_s_c k) -{ - int ret; - - ret = bch2_data_move(c, ctxt, &tier->devs, k, NULL); - if (!ret) - trace_tiering_copy(k.k); - else - trace_tiering_alloc_fail(c, k.k->size); - - return ret; -} - -/** - * tiering_next_cache - issue a move to write an extent to the next cache - * device in round robin order - */ -static s64 read_tiering(struct bch_fs *c, struct bch_tier *tier) -{ - struct moving_context ctxt; - struct btree_iter iter; - struct bkey_s_c k; - unsigned nr_devices = dev_mask_nr(&tier->devs); - int ret; - - if (!nr_devices) - return 0; - - trace_tiering_start(c); - - bch2_move_ctxt_init(&ctxt, &tier->pd.rate, - nr_devices * SECTORS_IN_FLIGHT_PER_DEVICE); - bch2_btree_iter_init(&iter, c, BTREE_ID_EXTENTS, POS_MIN, - BTREE_ITER_PREFETCH); - - while (!kthread_should_stop() && - !bch2_move_ctxt_wait(&ctxt) && - (k = bch2_btree_iter_peek(&iter)).k && - !btree_iter_err(k)) { - if (!tiering_pred(c, tier, k)) - goto next; - - ret = issue_tiering_move(c, tier, &ctxt, k); - if (ret) { - bch2_btree_iter_unlock(&iter); - - /* memory allocation failure, wait for some IO to finish */ - bch2_move_ctxt_wait_for_io(&ctxt); - continue; - } -next: - bch2_btree_iter_advance_pos(&iter); - //bch2_btree_iter_cond_resched(&iter); + struct bch_tier *tier = arg; + struct bch_fs *c = container_of(tier, struct bch_fs, tiers[tier->idx]); + const struct bch_extent_ptr *ptr; + unsigned replicas = 0; - /* unlock before calling moving_context_wait() */ - bch2_btree_iter_unlock(&iter); - cond_resched(); - } + /* Make sure we have room to add a new pointer: */ + if (bkey_val_u64s(e.k) + BKEY_EXTENT_PTR_U64s_MAX > + BKEY_EXTENT_VAL_U64s_MAX) + return false; - bch2_btree_iter_unlock(&iter); - bch2_move_ctxt_exit(&ctxt); - trace_tiering_end(c, ctxt.sectors_moved, ctxt.keys_moved); + extent_for_each_ptr(e, ptr) + if (c->devs[ptr->dev]->mi.tier >= tier->idx) + replicas++; - return ctxt.sectors_moved; + return replicas < c->opts.data_replicas; } static int bch2_tiering_thread(void *arg) @@ -122,15 +40,15 @@ static int bch2_tiering_thread(void *arg) struct bch_fs *c = container_of(tier, struct bch_fs, tiers[tier->idx]); struct io_clock *clock = &c->io_clock[WRITE]; struct bch_dev *ca; - u64 tier_capacity, available_sectors; + u64 tier_capacity, available_sectors, keys_moved, sectors_moved; unsigned long last; - unsigned i; + unsigned i, nr_devices; set_freezable(); while (!kthread_should_stop()) { if (kthread_wait_freezable(c->tiering_enabled && - dev_mask_nr(&tier->devs))) + (nr_devices = dev_mask_nr(&tier->devs)))) break; while (1) { @@ -151,7 +69,7 @@ static int bch2_tiering_thread(void *arg) ca->mi.first_bucket); available_sectors += bucket_to_sector(ca, - dev_buckets_available(ca)); + dev_buckets_available(c, ca)); } rcu_read_unlock(); } @@ -167,7 +85,15 @@ static int bch2_tiering_thread(void *arg) return 0; } - read_tiering(c, tier); + bch2_move_data(c, &tier->pd.rate, + SECTORS_IN_FLIGHT_PER_DEVICE * nr_devices, + &tier->devs, + writepoint_ptr(&tier->wp), + 0, + -1, + tiering_pred, tier, + &keys_moved, + §ors_moved); } return 0; |