mirror of https://gitee.com/openkylin/qemu.git
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>
This commit is contained in:
parent
4fb588e95b
commit
eb05e011e2
10
blockjob.c
10
blockjob.c
|
@ -771,7 +771,14 @@ void block_job_resume_all(void)
|
||||||
|
|
||||||
void block_job_enter(BlockJob *job)
|
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);
|
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);
|
aio_context_acquire(aio_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->job->deferred_to_main_loop = false;
|
|
||||||
data->fn(data->job, data->opaque);
|
data->fn(data->job, data->opaque);
|
||||||
|
|
||||||
if (aio_context != data->aio_context) {
|
if (aio_context != data->aio_context) {
|
||||||
|
|
|
@ -241,7 +241,8 @@ typedef void BlockJobDeferToMainLoopFn(BlockJob *job, void *opaque);
|
||||||
* @fn: The function to run in the main loop
|
* @fn: The function to run in the main loop
|
||||||
* @opaque: The opaque value that is passed to @fn
|
* @opaque: The opaque value that is passed to @fn
|
||||||
*
|
*
|
||||||
* Execute a given function in the main loop with the BlockDriverState
|
* This function must be called by the main job coroutine just before it
|
||||||
|
* returns. @fn is executed in the main loop with the BlockDriverState
|
||||||
* AioContext acquired. Block jobs must call bdrv_unref(), bdrv_close(), and
|
* AioContext acquired. Block jobs must call bdrv_unref(), bdrv_close(), and
|
||||||
* anything that uses bdrv_drain_all() in the main loop.
|
* anything that uses bdrv_drain_all() in the main loop.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue