Skip to content
  • Hanna Reitz's avatar
    0bc329fb
    block: block-status cache for data regions · 0bc329fb
    Hanna Reitz authored
    As we have attempted before
    (https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg06451.html,
    "file-posix: Cache lseek result for data regions";
    https://lists.nongnu.org/archive/html/qemu-block/2021-02/msg00934.html,
    "file-posix: Cache next hole"), this patch seeks to reduce the number of
    SEEK_DATA/HOLE operations the file-posix driver has to perform.  The
    main difference is that this time it is implemented as part of the
    general block layer code.
    
    The problem we face is that on some filesystems or in some
    circumstances, SEEK_DATA/HOLE is unreasonably slow.  Given the
    implementation is outside of qemu, there is little we can do about its
    performance.
    
    We have already introduced the want_zero parameter to
    bdrv_co_block_status() to reduce the number of SEEK_DATA/HOLE calls
    unless we really want zero information; but sometimes we do want that
    information, because for files that consist largely of zero areas,
    special-casing those areas can give large performance boosts.  So the
    real problem is with files that consist largely of data, so that
    inquiring the block status does not gain us much performance, but where
    such an inquiry itself takes a lot of time.
    
    To address this, we want to cache data regions.  Most of the time, when
    bad performance is reported, it is in places where the image is iterated
    over from start to end (qemu-img convert or the mirror job), so a simple
    yet effective solution is to cache only the current data region.
    
    (Note that only caching data regions but not zero regions means that
    returning false information from the cache is not catastrophic: Treating
    zeroes as data is fine.  While we try to invalidate the cache on zero
    writes and discards, such incongruences may still occur when there are
    other processes writing to the image.)
    
    We only use the cache for nodes without children (i.e. protocol nodes),
    because that is where the problem is: Drivers that rely on block-status
    implementations outside of qemu (e.g. SEEK_DATA/HOLE).
    
    Resolves: https://gitlab.com/qemu-project/qemu/-/issues/307
    
    
    Signed-off-by: default avatarHanna Reitz <hreitz@redhat.com>
    Message-Id: <20210812084148.14458-3-hreitz@redhat.com>
    Reviewed-by: default avatarEric Blake <eblake@redhat.com>
    Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
    [hreitz: Added `local_file == bs` assertion, as suggested by Vladimir]
    Signed-off-by: default avatarHanna Reitz <hreitz@redhat.com>
    0bc329fb
    block: block-status cache for data regions
    Hanna Reitz authored
    As we have attempted before
    (https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg06451.html,
    "file-posix: Cache lseek result for data regions";
    https://lists.nongnu.org/archive/html/qemu-block/2021-02/msg00934.html,
    "file-posix: Cache next hole"), this patch seeks to reduce the number of
    SEEK_DATA/HOLE operations the file-posix driver has to perform.  The
    main difference is that this time it is implemented as part of the
    general block layer code.
    
    The problem we face is that on some filesystems or in some
    circumstances, SEEK_DATA/HOLE is unreasonably slow.  Given the
    implementation is outside of qemu, there is little we can do about its
    performance.
    
    We have already introduced the want_zero parameter to
    bdrv_co_block_status() to reduce the number of SEEK_DATA/HOLE calls
    unless we really want zero information; but sometimes we do want that
    information, because for files that consist largely of zero areas,
    special-casing those areas can give large performance boosts.  So the
    real problem is with files that consist largely of data, so that
    inquiring the block status does not gain us much performance, but where
    such an inquiry itself takes a lot of time.
    
    To address this, we want to cache data regions.  Most of the time, when
    bad performance is reported, it is in places where the image is iterated
    over from start to end (qemu-img convert or the mirror job), so a simple
    yet effective solution is to cache only the current data region.
    
    (Note that only caching data regions but not zero regions means that
    returning false information from the cache is not catastrophic: Treating
    zeroes as data is fine.  While we try to invalidate the cache on zero
    writes and discards, such incongruences may still occur when there are
    other processes writing to the image.)
    
    We only use the cache for nodes without children (i.e. protocol nodes),
    because that is where the problem is: Drivers that rely on block-status
    implementations outside of qemu (e.g. SEEK_DATA/HOLE).
    
    Resolves: https://gitlab.com/qemu-project/qemu/-/issues/307
    
    
    Signed-off-by: default avatarHanna Reitz <hreitz@redhat.com>
    Message-Id: <20210812084148.14458-3-hreitz@redhat.com>
    Reviewed-by: default avatarEric Blake <eblake@redhat.com>
    Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
    [hreitz: Added `local_file == bs` assertion, as suggested by Vladimir]
    Signed-off-by: default avatarHanna Reitz <hreitz@redhat.com>
Loading