Skip to content
  • Emanuele Giuseppe Esposito's avatar
    c86422c5
    block: Convert bdrv_refresh_total_sectors() to co_wrapper_mixed · c86422c5
    Emanuele Giuseppe Esposito authored
    
    
    BlockDriver->bdrv_getlength is categorized as IO callback, and it
    currently doesn't run in a coroutine. We should let it take a graph
    rdlock since the callback traverses the block nodes graph, which however
    is only possible in a coroutine.
    
    Therefore turn it into a co_wrapper to move the actual function into a
    coroutine where the lock can be taken.
    
    Because now this function creates a new coroutine and polls, we need to
    take the AioContext lock where it is missing, for the only reason that
    internally co_wrapper calls AIO_WAIT_WHILE and it expects to release the
    AioContext lock.
    
    This is especially messy when a co_wrapper creates a coroutine and polls
    in bdrv_open_driver, because this function has so many callers in so
    many context that it can easily lead to deadlocks. Therefore the new
    rule for bdrv_open_driver is that the caller must always hold the
    AioContext lock of the given bs (except if it is a coroutine), because
    the function calls bdrv_refresh_total_sectors() which is now a
    co_wrapper.
    
    Once the rwlock is ultimated and placed in every place it needs to be,
    we will poll using AIO_WAIT_WHILE_UNLOCKED and remove the AioContext
    lock.
    
    Signed-off-by: default avatarEmanuele Giuseppe Esposito <eesposit@redhat.com>
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    Message-Id: <20230113204212.359076-7-kwolf@redhat.com>
    Reviewed-by: default avatarEmanuele Giuseppe Esposito <eesposit@redhat.com>
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    c86422c5
    block: Convert bdrv_refresh_total_sectors() to co_wrapper_mixed
    Emanuele Giuseppe Esposito authored
    
    
    BlockDriver->bdrv_getlength is categorized as IO callback, and it
    currently doesn't run in a coroutine. We should let it take a graph
    rdlock since the callback traverses the block nodes graph, which however
    is only possible in a coroutine.
    
    Therefore turn it into a co_wrapper to move the actual function into a
    coroutine where the lock can be taken.
    
    Because now this function creates a new coroutine and polls, we need to
    take the AioContext lock where it is missing, for the only reason that
    internally co_wrapper calls AIO_WAIT_WHILE and it expects to release the
    AioContext lock.
    
    This is especially messy when a co_wrapper creates a coroutine and polls
    in bdrv_open_driver, because this function has so many callers in so
    many context that it can easily lead to deadlocks. Therefore the new
    rule for bdrv_open_driver is that the caller must always hold the
    AioContext lock of the given bs (except if it is a coroutine), because
    the function calls bdrv_refresh_total_sectors() which is now a
    co_wrapper.
    
    Once the rwlock is ultimated and placed in every place it needs to be,
    we will poll using AIO_WAIT_WHILE_UNLOCKED and remove the AioContext
    lock.
    
    Signed-off-by: default avatarEmanuele Giuseppe Esposito <eesposit@redhat.com>
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    Message-Id: <20230113204212.359076-7-kwolf@redhat.com>
    Reviewed-by: default avatarEmanuele Giuseppe Esposito <eesposit@redhat.com>
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Loading