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)
 | 
			
		||||
{
 | 
			
		||||
    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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -241,7 +241,8 @@ typedef void BlockJobDeferToMainLoopFn(BlockJob *job, void *opaque);
 | 
			
		|||
 * @fn: The function to run in the main loop
 | 
			
		||||
 * @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
 | 
			
		||||
 * anything that uses bdrv_drain_all() in the main loop.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue