qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: John Snow <jsnow@redhat.com>
To: Fam Zheng <famz@redhat.com>, qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Jeff Cody <jcody@redhat.com>,
	Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	qemu-block@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 08/13] block: Support meta dirty bitmap
Date: Thu, 7 Jan 2016 14:30:27 -0500	[thread overview]
Message-ID: <568EBCD3.10203@redhat.com> (raw)
In-Reply-To: <1451903234-32529-9-git-send-email-famz@redhat.com>



On 01/04/2016 05:27 AM, Fam Zheng wrote:
> The added group of operations enables tracking of the changed bits in
> the dirty bitmap.
> 
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  block/dirty-bitmap.c         | 51 ++++++++++++++++++++++++++++++++++++++++++++
>  include/block/dirty-bitmap.h |  9 ++++++++
>  2 files changed, 60 insertions(+)
> 
> diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
> index 53cf88d..4314659 100644
> --- a/block/dirty-bitmap.c
> +++ b/block/dirty-bitmap.c
> @@ -37,6 +37,7 @@
>   */
>  struct BdrvDirtyBitmap {
>      HBitmap *bitmap;            /* Dirty sector bitmap implementation */
> +    HBitmap *meta;              /* Meta dirty bitmap */

IMO, this gets a little strange -- if I understand correctly, you're
using this meta pointer as a cache for the meta bitmap contained within
"bitmap," and not actually creating a new "standalone" HBitmap.

Since it has the same type as the prior "bitmap" member, though, it
makes it look like they're both the same kind of object ... when in
fact, one is the child of the other.

It's probably fine, but I was momentarily confused. I don't have a
better suggestion.

>      BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
>      char *name;                 /* Optional non-empty unique ID */
>      int64_t size;               /* Size of the bitmap (Number of sectors) */
> @@ -102,6 +103,56 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
>      return bitmap;
>  }
>  
> +/* bdrv_create_meta_dirty_bitmap
> + *
> + * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
> + * when a dirty status bit in @bitmap is changed (either from reset to set or
> + * the other way around), its respective meta dirty bitmap bit will be marked
> + * dirty as well.
> + *
> + * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
> + * @granularity: how many bytes of bitmap data does each bit in the meta bitmap
> + * track.
> + */
> +void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
> +                                   int granularity)
> +{
> +    assert(!bitmap->meta);
> +    bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
> +                                       BDRV_SECTOR_SIZE * BITS_PER_BYTE);
> +}
> +
> +void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
> +{
> +    assert(bitmap->meta);
> +    hbitmap_free(bitmap->meta);

This leaves a dangling pointer inside the Hbitmap, no?

> +    bitmap->meta = NULL;
> +}
> +
> +int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
> +                               BdrvDirtyBitmap *bitmap, int64_t sector,
> +                               int nb_sectors)
> +{
> +    uint64_t i;
> +    int gran = bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
> +
> +    /* To optimize: we can make hbitmap to internally check the range in a
> +     * coarse level, or at least do it word by word. */
> +    for (i = sector; i < sector + nb_sectors; i += gran) {
> +        if (hbitmap_get(bitmap->meta, i)) {
> +            return true;
> +        }
> +    }
> +    return false;
> +}
> +

In essence get_meta() is a greedy algorithm that simply returns true if
anything is set between [sector, sector + nb_sectors], yes?

Is this more useful than just using an iterator directly on the
meta-bitmap?

I haven't finished reading but, I imagine that:

- If we need to check to see what is dirty specifically, we can just use
the iterator. If the iterator doesn't return anything, we know it's
empty. If it does return, we know exactly what's dirty.
- If we need to explicitly check for emptiness in general, we can use
the internal popcount.


I'm not sure when a 'dirty range bool' will be explicitly useful all by
itself, but maybe that becomes obvious later.

> +void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
> +                                  BdrvDirtyBitmap *bitmap, int64_t sector,
> +                                  int nb_sectors)
> +{
> +    hbitmap_reset(bitmap->meta, sector, nb_sectors);
> +}
> +
>  bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
>  {
>      return bitmap->successor;
> diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
> index 16bb15a..0715220 100644
> --- a/include/block/dirty-bitmap.h
> +++ b/include/block/dirty-bitmap.h
> @@ -8,6 +8,9 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
>                                            uint32_t granularity,
>                                            const char *name,
>                                            Error **errp);
> +void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
> +                                   int granularity);
> +void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap);
>  int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
>                                         BdrvDirtyBitmap *bitmap,
>                                         Error **errp);
> @@ -34,6 +37,12 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
>                             int64_t cur_sector, int nr_sectors);
>  void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
>                               int64_t cur_sector, int nr_sectors);
> +int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
> +                               BdrvDirtyBitmap *bitmap, int64_t sector,
> +                               int nb_sectors);
> +void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
> +                                  BdrvDirtyBitmap *bitmap, int64_t sector,
> +                                  int nb_sectors);
>  BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
>                                           uint64_t first_sector);
>  void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);
> 

  reply	other threads:[~2016-01-07 19:30 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-04 10:27 [Qemu-devel] [PATCH 00/13] Dirty bitmap changes for migration/persistence work Fam Zheng
2016-01-04 10:27 ` [Qemu-devel] [PATCH 01/13] backup: Use Bitmap to replace "s->bitmap" Fam Zheng
2016-01-04 10:27 ` [Qemu-devel] [PATCH 02/13] typedefs: Add BdrvDirtyBitmap and HBitmapIter Fam Zheng
2016-01-05 22:14   ` John Snow
2016-01-08  2:13     ` Fam Zheng
2016-01-04 10:27 ` [Qemu-devel] [PATCH 03/13] block: Move block dirty bitmap code to separate files Fam Zheng
2016-01-05 22:32   ` John Snow
2016-01-04 10:27 ` [Qemu-devel] [PATCH 04/13] block: Remove unused typedef of BlockDriverDirtyHandler Fam Zheng
2016-01-05 22:35   ` John Snow
2016-01-04 10:27 ` [Qemu-devel] [PATCH 05/13] block: Hide HBitmap in block dirty bitmap interface Fam Zheng
2016-01-05 23:01   ` John Snow
2016-01-20  5:09     ` Fam Zheng
2016-01-04 10:27 ` [Qemu-devel] [PATCH 06/13] HBitmap: Introduce "meta" bitmap to track bit changes Fam Zheng
2016-01-06  0:09   ` John Snow
2016-01-11 15:40   ` Vladimir Sementsov-Ogievskiy
2016-01-11 18:56     ` John Snow
2016-01-12  8:25       ` Vladimir Sementsov-Ogievskiy
2016-01-04 10:27 ` [Qemu-devel] [PATCH 07/13] tests: Add test code for meta bitmap Fam Zheng
2016-01-06 20:46   ` John Snow
2016-01-04 10:27 ` [Qemu-devel] [PATCH 08/13] block: Support meta dirty bitmap Fam Zheng
2016-01-07 19:30   ` John Snow [this message]
2016-01-20  6:07     ` Fam Zheng
2016-01-20 21:46       ` John Snow
2016-01-04 10:27 ` [Qemu-devel] [PATCH 09/13] block: Add two dirty bitmap getters Fam Zheng
2016-01-07 19:35   ` John Snow
2016-01-04 10:27 ` [Qemu-devel] [PATCH 10/13] block: Assert that bdrv_release_dirty_bitmap succeeded Fam Zheng
2016-01-07 19:38   ` John Snow
2016-01-04 10:27 ` [Qemu-devel] [PATCH 11/13] hbitmap: serialization Fam Zheng
2016-01-07 21:11   ` John Snow
2016-01-11 15:12     ` Vladimir Sementsov-Ogievskiy
2016-01-11 14:48   ` Vladimir Sementsov-Ogievskiy
2016-01-11 15:19   ` Vladimir Sementsov-Ogievskiy
2016-01-04 10:27 ` [Qemu-devel] [PATCH 12/13] block: BdrvDirtyBitmap serialization interface Fam Zheng
2016-01-04 10:27 ` [Qemu-devel] [PATCH 13/13] tests: Add test code for hbitmap serialization Fam Zheng
2016-01-07 21:32 ` [Qemu-devel] [PATCH 00/13] Dirty bitmap changes for migration/persistence work John Snow
2016-01-08  0:29   ` Fam Zheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=568EBCD3.10203@redhat.com \
    --to=jsnow@redhat.com \
    --cc=famz@redhat.com \
    --cc=jcody@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).