Skip to content
  • Kevin Wolf's avatar
    b5a7a057
    blockjob: Lie better in child_job_drained_poll() · b5a7a057
    Kevin Wolf authored
    
    
    Block jobs claim in .drained_poll() that they are in a quiescent state
    as soon as job->deferred_to_main_loop is true. This is obviously wrong,
    they still have a completion BH to run. We only get away with this
    because commit 91af091f added an unconditional aio_poll(false) to the
    drain functions, but this is bypassing the regular drain mechanisms.
    
    However, just removing this and telling that the job is still active
    doesn't work either: The completion callbacks themselves call drain
    functions (directly, or indirectly with bdrv_reopen), so they would
    deadlock then.
    
    As a better lie, tell that the job is active as long as the BH is
    pending, but falsely call it quiescent from the point in the BH when the
    completion callback is called. At this point, nested drain calls won't
    deadlock because they ignore the job, and outer drains will wait for the
    job to really reach a quiescent state because the callback is already
    running.
    
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
    b5a7a057
    blockjob: Lie better in child_job_drained_poll()
    Kevin Wolf authored
    
    
    Block jobs claim in .drained_poll() that they are in a quiescent state
    as soon as job->deferred_to_main_loop is true. This is obviously wrong,
    they still have a completion BH to run. We only get away with this
    because commit 91af091f added an unconditional aio_poll(false) to the
    drain functions, but this is bypassing the regular drain mechanisms.
    
    However, just removing this and telling that the job is still active
    doesn't work either: The completion callbacks themselves call drain
    functions (directly, or indirectly with bdrv_reopen), so they would
    deadlock then.
    
    As a better lie, tell that the job is active as long as the BH is
    pending, but falsely call it quiescent from the point in the BH when the
    completion callback is called. At this point, nested drain calls won't
    deadlock because they ignore the job, and outer drains will wait for the
    job to really reach a quiescent state because the callback is already
    running.
    
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Loading