aboutsummaryrefslogtreecommitdiff
path: root/blockjob.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2017-05-08 16:13:10 +0200
committerJeff Cody <jcody@redhat.com>2017-05-24 16:38:51 -0400
commiteb05e011e248c6fb6baee295e14fd206e136028c (patch)
treeab38894e8cee57f1e1d2ca690b74bc00800673cb /blockjob.c
parent4fb588e95bacb770746cc794ef165fd71a4d27ea (diff)
downloadqemu-eb05e011e248c6fb6baee295e14fd206e136028c.zip
qemu-eb05e011e248c6fb6baee295e14fd206e136028c.tar.gz
qemu-eb05e011e248c6fb6baee295e14fd206e136028c.tar.bz2
blockjob: use deferred_to_main_loop to indicate the coroutine has ended
All block jobs are using block_job_defer_to_main_loop as the final step just before the coroutine terminates. At this point, block_job_enter should do nothing, but currently it restarts the freed coroutine. Now, the job->co states should probably be changed to an enum (e.g. BEFORE_START, STARTED, YIELDED, COMPLETED) subsuming block_job_started, job->deferred_to_main_loop and job->busy. For now, this patch eliminates the problematic reenter by removing the reset of job->deferred_to_main_loop (which served no purpose, as far as I could see) and checking the flag in block_job_enter. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-id: 20170508141310.8674-12-pbonzini@redhat.com Signed-off-by: Jeff Cody <jcody@redhat.com>
Diffstat (limited to 'blockjob.c')
-rw-r--r--blockjob.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/blockjob.c b/blockjob.c
index 9a97c73..a0d7e29 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -771,7 +771,14 @@ void block_job_resume_all(void)
void block_job_enter(BlockJob *job)
{
- if (job->co && !job->busy) {
+ if (!block_job_started(job)) {
+ return;
+ }
+ if (job->deferred_to_main_loop) {
+ return;
+ }
+
+ if (!job->busy) {
bdrv_coroutine_enter(blk_bs(job->blk), job->co);
}
}
@@ -899,7 +906,6 @@ static void block_job_defer_to_main_loop_bh(void *opaque)
aio_context_acquire(aio_context);
}
- data->job->deferred_to_main_loop = false;
data->fn(data->job, data->opaque);
if (aio_context != data->aio_context) {