Skip to content
  • Kevin Wolf's avatar
    cf312932
    block-backend: Queue requests while drained · cf312932
    Kevin Wolf authored
    
    
    This fixes devices like IDE that can still start new requests from I/O
    handlers in the CPU thread while the block backend is drained.
    
    The basic assumption is that in a drain section, no new requests should
    be allowed through a BlockBackend (blk_drained_begin/end don't exist,
    we get drain sections only on the node level). However, there are two
    special cases where requests should not be queued:
    
    1. Block jobs: We already make sure that block jobs are paused in a
       drain section, so they won't start new requests. However, if the
       drain_begin is called on the job's BlockBackend first, it can happen
       that we deadlock because the job stays busy until it reaches a pause
       point - which it can't if its requests aren't processed any more.
    
       The proper solution here would be to make all requests through the
       job's filter node instead of using a BlockBackend. For now, just
       disabling request queuing on the job BlockBackend is simpler.
    
    2. In test cases where making requests through bdrv_* would be
       cumbersome because we'd need a BdrvChild. As we already got the
       functionality to disable request queuing from 1., use it in tests,
       too, for convenience.
    
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
    cf312932
    block-backend: Queue requests while drained
    Kevin Wolf authored
    
    
    This fixes devices like IDE that can still start new requests from I/O
    handlers in the CPU thread while the block backend is drained.
    
    The basic assumption is that in a drain section, no new requests should
    be allowed through a BlockBackend (blk_drained_begin/end don't exist,
    we get drain sections only on the node level). However, there are two
    special cases where requests should not be queued:
    
    1. Block jobs: We already make sure that block jobs are paused in a
       drain section, so they won't start new requests. However, if the
       drain_begin is called on the job's BlockBackend first, it can happen
       that we deadlock because the job stays busy until it reaches a pause
       point - which it can't if its requests aren't processed any more.
    
       The proper solution here would be to make all requests through the
       job's filter node instead of using a BlockBackend. For now, just
       disabling request queuing on the job BlockBackend is simpler.
    
    2. In test cases where making requests through bdrv_* would be
       cumbersome because we'd need a BdrvChild. As we already got the
       functionality to disable request queuing from 1., use it in tests,
       too, for convenience.
    
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Loading