Commit 261af2f1 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: Make sure bch2_move_ratelimit() also waits for move_ops

This adds move_ctxt_wait_event_timeout(), which can sleep for a timeout
while also issueing pending moves as reads complete.
Co-developed-by: default avatarDaniel Hill <daniel@gluo.nz>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 50e029c6
......@@ -500,22 +500,13 @@ int bch2_move_ratelimit(struct moving_context *ctxt)
do {
delay = ctxt->rate ? bch2_ratelimit_delay(ctxt->rate) : 0;
if (delay) {
if (delay > HZ / 10)
bch2_trans_unlock_long(ctxt->trans);
else
bch2_trans_unlock(ctxt->trans);
set_current_state(TASK_INTERRUPTIBLE);
}
if ((current->flags & PF_KTHREAD) && kthread_should_stop()) {
__set_current_state(TASK_RUNNING);
if ((current->flags & PF_KTHREAD) && kthread_should_stop())
return 1;
}
if (delay)
schedule_timeout(delay);
move_ctxt_wait_event_timeout(ctxt,
freezing(current) || kthread_should_stop(),
delay);
if (unlikely(freezing(current))) {
bch2_moving_ctxt_flush_all(ctxt);
......
......@@ -38,6 +38,25 @@ struct moving_context {
wait_queue_head_t wait;
};
#define move_ctxt_wait_event_timeout(_ctxt, _cond, _timeout) \
({ \
int _ret = 0; \
while (true) { \
bool cond_finished = false; \
bch2_moving_ctxt_do_pending_writes(_ctxt); \
\
if (_cond) \
break; \
bch2_trans_unlock_long((_ctxt)->trans); \
_ret = __wait_event_timeout((_ctxt)->wait, \
bch2_moving_ctxt_next_pending_write(_ctxt) || \
(cond_finished = (_cond)), _timeout); \
if (_ret || ( cond_finished)) \
break; \
} \
_ret; \
})
#define move_ctxt_wait_event(_ctxt, _cond) \
do { \
bool cond_finished = false; \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment