[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-block] [Qemu-devel] [PATCH v3 3/8] dirty-bitmap: add bdrv_dirt
From: |
John Snow |
Subject: |
Re: [Qemu-block] [Qemu-devel] [PATCH v3 3/8] dirty-bitmap: add bdrv_dirty_bitmap_next_dirty_area |
Date: |
Mon, 10 Sep 2018 16:42:26 -0400 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 |
On 08/14/2018 08:14 AM, Vladimir Sementsov-Ogievskiy wrote:
> The function alters bdrv_dirty_iter_next_area(), which is wrong and
> less efficient (see further commit
> "block/mirror: fix and improve do_sync_target_write" for description).
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <address@hidden>
> ---
> include/block/dirty-bitmap.h | 3 +++
> include/qemu/hbitmap.h | 15 +++++++++++++++
> block/dirty-bitmap.c | 7 +++++++
> util/hbitmap.c | 38 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 63 insertions(+)
>
> diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
> index 27f5299c4e..cb9162fa7e 100644
> --- a/include/block/dirty-bitmap.h
> +++ b/include/block/dirty-bitmap.h
> @@ -100,6 +100,9 @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState
> *bs,
> char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp);
> int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t start,
> int64_t end);
> +bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
> + uint64_t *offset, uint64_t end,
> + uint64_t *length);
> BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
> BdrvDirtyBitmap *bitmap,
> Error **errp);
> diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
> index fe4dfde27a..7800317bf3 100644
> --- a/include/qemu/hbitmap.h
> +++ b/include/qemu/hbitmap.h
> @@ -306,6 +306,21 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi);
> */
> int64_t hbitmap_next_zero(const HBitmap *hb, uint64_t start, int64_t end);
>
> +/* hbitmap_next_dirty_area:
> + * @hb: The HBitmap to operate on
> + * @offset: in-out parameter.
> + * in: the offset to start from
> + * out: (if area found) start of found area
> + * @end: end of requested region. (address@hidden + address@hidden) will be
> <= @end
> + * @length: length of found area
> + *
> + * If dirty area found within address@hidden, @end), returns true and sets
> @offset
> + * and @length appropriately. Otherwise returns true and leaves @offset and
> + * @length unchanged.
It returns true in both cases? I think you mean 'false' the second time.
> + */
> +bool hbitmap_next_dirty_area(const HBitmap *hb, uint64_t *offset,
> + uint64_t end, uint64_t *length);
> +
> /* hbitmap_create_meta:
> * Create a "meta" hbitmap to track dirtiness of the bits in this HBitmap.
> * The caller owns the created bitmap and must call hbitmap_free_meta(hb) to
> diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
> index 037ae62726..4af20a1beb 100644
> --- a/block/dirty-bitmap.c
> +++ b/block/dirty-bitmap.c
> @@ -791,6 +791,13 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap
> *bitmap, uint64_t offset,
> return hbitmap_next_zero(bitmap->bitmap, offset, end);
> }
>
> +bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
> + uint64_t *offset, uint64_t end,
> + uint64_t *length)
> +{
> + return hbitmap_next_dirty_area(bitmap->bitmap, offset, end, length);
> +}
> +
> void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap
> *src,
> Error **errp)
> {
> diff --git a/util/hbitmap.c b/util/hbitmap.c
> index 1687372504..bf88c1223e 100644
> --- a/util/hbitmap.c
> +++ b/util/hbitmap.c
> @@ -244,6 +244,44 @@ int64_t hbitmap_next_zero(const HBitmap *hb, uint64_t
> start, int64_t end)
> return res;
> }
>
> +bool hbitmap_next_dirty_area(const HBitmap *hb, uint64_t *offset,
> + uint64_t end, uint64_t *length)
> +{
> + HBitmapIter hbi;
> + int64_t off1, off0;
Can we have more descriptive names for these?
> + uint32_t granularity = 1UL << hb->granularity;
> +
> + if (end == 0) {
> + end = hb->orig_size;
> + }
> +
> + hbitmap_iter_init(&hbi, hb, *offset);
Even with a new iterator in every call, this is still faster than the
old one? ... I guess the old one uses a new iterator for every call, too.
Well, this does look more straightforward and we don't loop as much, so
it seems right.
> + off1 = hbitmap_iter_next(&hbi, true);
> +
> + if (off1 < 0 || off1 >= end) {
> + return false;
> + }
> +
> + if (off1 + granularity >= end) {
> + if (off1 > *offset) {
> + *offset = off1;
> + }
> + *length = end - *offset;
> + return true;
> + }
> +
> + off0 = hbitmap_next_zero(hb, off1 + granularity, end);
> + if (off0 < 0) {
> + off0 = end;
> + }
> +
> + if (off1 > *offset) {
> + *offset = off1;
> + }
> + *length = off0 - *offset;
> + return true;
> +}
> +
I might have consolidated setting the output parameters to one block
instead of two, but that's only stylistic.
> bool hbitmap_empty(const HBitmap *hb)
> {
> return hb->count == 0;
>
If you fix your docstring:
Reviewed-by: John Snow <address@hidden>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-block] [Qemu-devel] [PATCH v3 3/8] dirty-bitmap: add bdrv_dirty_bitmap_next_dirty_area,
John Snow <=