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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Paolo Bonzini
						Paolo Bonzini