summaryrefslogtreecommitdiff
path: root/libbcachefs/tier.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/tier.c')
-rw-r--r--libbcachefs/tier.c126
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,
+ &sectors_moved);
}
return 0;