diff options
author | Kevin Wolf <kwolf@redhat.com> | 2023-05-10 22:36:00 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2023-05-19 19:12:12 +0200 |
commit | 018e5987b57589e6e9089c2d2ef31db4e7519fd5 (patch) | |
tree | 648465e9b4825e51bc1c712ce77453114a5cb096 /block/stream.c | |
parent | 01a10c243362e49afcb7acbd85a47eba64a6fc74 (diff) | |
download | qemu-018e5987b57589e6e9089c2d2ef31db4e7519fd5.zip qemu-018e5987b57589e6e9089c2d2ef31db4e7519fd5.tar.gz qemu-018e5987b57589e6e9089c2d2ef31db4e7519fd5.tar.bz2 |
blockjob: Adhere to rate limit even when reentered early
When jobs are sleeping, for example to enforce a given rate limit, they
can be reentered early, in particular in order to get paused, to update
the rate limit or to get cancelled.
Before this patch, they behave in this case as if they had fully
completed their rate limiting delay. This means that requests are sped
up beyond their limit, violating the constraints that the user gave us.
Change the block jobs to sleep in a loop until the necessary delay is
completed, while still allowing cancelling them immediately as well
pausing (handled by the pause point in job_sleep_ns()) and updating the
rate limit.
This change is also motivated by iotests cases being prone to fail
because drain operations pause and unpause them so often that block jobs
complete earlier than they are supposed to. In particular, the next
commit would fail iotests 030 without this change.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20230510203601.418015-8-kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/stream.c')
-rw-r--r-- | block/stream.c | 7 |
1 files changed, 2 insertions, 5 deletions
diff --git a/block/stream.c b/block/stream.c index 7f9e1ec..e522bbd 100644 --- a/block/stream.c +++ b/block/stream.c @@ -131,7 +131,6 @@ static int coroutine_fn stream_run(Job *job, Error **errp) BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs); int64_t len; int64_t offset = 0; - uint64_t delay_ns = 0; int error = 0; int64_t n = 0; /* bytes */ @@ -155,7 +154,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp) /* Note that even when no rate limit is applied we need to yield * with no pending I/O here so that bdrv_drain_all() returns. */ - job_sleep_ns(&s->common.job, delay_ns); + block_job_ratelimit_sleep(&s->common); if (job_is_cancelled(&s->common.job)) { break; } @@ -204,9 +203,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp) /* Publish progress */ job_progress_update(&s->common.job, n); if (copy) { - delay_ns = block_job_ratelimit_get_delay(&s->common, n); - } else { - delay_ns = 0; + block_job_ratelimit_processed_bytes(&s->common, n); } } |