From eb05e011e248c6fb6baee295e14fd206e136028c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 8 May 2017 16:13:10 +0200 Subject: 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 Signed-off-by: Paolo Bonzini Message-id: 20170508141310.8674-12-pbonzini@redhat.com Signed-off-by: Jeff Cody --- blockjob.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'blockjob.c') diff --git a/blockjob.c b/blockjob.c index 9a97c73d77..a0d7e29b83 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) { -- cgit v1.2.1