diff options
Diffstat (limited to 'fs/bcachefs')
-rw-r--r-- | fs/bcachefs/move.c | 22 | ||||
-rw-r--r-- | fs/bcachefs/move.h | 2 | ||||
-rw-r--r-- | fs/bcachefs/opts.h | 7 |
3 files changed, 24 insertions, 7 deletions
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index d0ce656755d7..c2226353c775 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -74,6 +74,7 @@ static void move_write_done(struct bch_write_op *op) ctxt->write_error = true; atomic_sub(io->write_sectors, &io->write.ctxt->write_sectors); + atomic_dec(&io->write.ctxt->write_ios); move_free(io); closure_put(&ctxt->cl); } @@ -87,6 +88,7 @@ static void move_write(struct moving_io *io) closure_get(&io->write.ctxt->cl); atomic_add(io->write_sectors, &io->write.ctxt->write_sectors); + atomic_inc(&io->write.ctxt->write_ios); bch2_data_update_read_done(&io->write, io->rbio.pick.crc); } @@ -105,6 +107,7 @@ static void move_read_endio(struct bio *bio) struct moving_context *ctxt = io->write.ctxt; atomic_sub(io->read_sectors, &ctxt->read_sectors); + atomic_dec(&ctxt->read_ios); io->read_completed = true; wake_up(&ctxt->wait); @@ -139,7 +142,11 @@ void bch2_moving_ctxt_exit(struct moving_context *ctxt) { move_ctxt_wait_event(ctxt, NULL, list_empty(&ctxt->reads)); closure_sync(&ctxt->cl); + EBUG_ON(atomic_read(&ctxt->write_sectors)); + EBUG_ON(atomic_read(&ctxt->write_ios)); + EBUG_ON(atomic_read(&ctxt->read_sectors)); + EBUG_ON(atomic_read(&ctxt->read_ios)); if (ctxt->stats) { progress_list_del(ctxt->c, ctxt->stats); @@ -314,6 +321,7 @@ static int bch2_move_extent(struct btree_trans *trans, trace_move_extent_read(k.k); atomic_add(io->read_sectors, &ctxt->read_sectors); + atomic_inc(&ctxt->read_ios); list_add_tail(&io->list, &ctxt->reads); /* @@ -403,13 +411,15 @@ static int move_ratelimit(struct btree_trans *trans, } } while (delay); + /* + * XXX: these limits really ought to be per device, SSDs and hard drives + * will want different limits + */ move_ctxt_wait_event(ctxt, trans, - atomic_read(&ctxt->write_sectors) < - c->opts.move_bytes_in_flight >> 9); - - move_ctxt_wait_event(ctxt, trans, - atomic_read(&ctxt->read_sectors) < - c->opts.move_bytes_in_flight >> 9); + atomic_read(&ctxt->write_sectors) < c->opts.move_bytes_in_flight >> 9 && + atomic_read(&ctxt->read_sectors) < c->opts.move_bytes_in_flight >> 9 && + atomic_read(&ctxt->write_ios) < c->opts.move_ios_in_flight && + atomic_read(&ctxt->read_ios) < c->opts.move_ios_in_flight); return 0; } diff --git a/fs/bcachefs/move.h b/fs/bcachefs/move.h index 34b9cadef6b5..aef613802935 100644 --- a/fs/bcachefs/move.h +++ b/fs/bcachefs/move.h @@ -24,6 +24,8 @@ struct moving_context { /* in flight sectors: */ atomic_t read_sectors; atomic_t write_sectors; + atomic_t read_ios; + atomic_t write_ios; wait_queue_head_t wait; }; diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h index ef1b8a03f149..fc444c68025c 100644 --- a/fs/bcachefs/opts.h +++ b/fs/bcachefs/opts.h @@ -299,7 +299,12 @@ enum opt_type { OPT_HUMAN_READABLE|OPT_FS|OPT_MOUNT|OPT_RUNTIME, \ OPT_UINT(1024, U32_MAX), \ BCH2_NO_SB_OPT, 1U << 20, \ - NULL, "Amount of IO in flight to keep in flight by the move path")\ + NULL, "Maximum Amount of IO to keep in flight by the move path")\ + x(move_ios_in_flight, u32, \ + OPT_FS|OPT_MOUNT|OPT_RUNTIME, \ + OPT_UINT(1, 1024), \ + BCH2_NO_SB_OPT, 32, \ + NULL, "Maximum number of IOs to keep in flight by the move path")\ x(fsck, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ |