Commit 50717e94 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Kevin Wolf
Browse files

block: allow customizing the granularity of the dirty bitmap

parent acc906c6
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@
#include "sysemu/blockdev.h"
#include <assert.h>

#define BLOCK_SIZE (BDRV_SECTORS_PER_DIRTY_CHUNK << BDRV_SECTOR_BITS)
#define BLOCK_SIZE                       (1 << 20)
#define BDRV_SECTORS_PER_DIRTY_CHUNK     (BLOCK_SIZE >> BDRV_SECTOR_BITS)

#define BLK_MIG_FLAG_DEVICE_BLOCK       0x01
#define BLK_MIG_FLAG_EOS                0x02
@@ -254,7 +255,7 @@ static void set_dirty_tracking(int enable)
    BlkMigDevState *bmds;

    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
        bdrv_set_dirty_tracking(bmds->bs, enable);
        bdrv_set_dirty_tracking(bmds->bs, enable ? BLOCK_SIZE : 0);
    }
}

+10 −7
Original line number Diff line number Diff line
@@ -2833,6 +2833,8 @@ BlockInfo *bdrv_query_info(BlockDriverState *bs)
        info->has_dirty = true;
        info->dirty = g_malloc0(sizeof(*info->dirty));
        info->dirty->count = bdrv_get_dirty_count(bs) * BDRV_SECTOR_SIZE;
        info->dirty->granularity =
            ((int64_t) BDRV_SECTOR_SIZE << hbitmap_granularity(bs->dirty_bitmap));
    }

    if (bs->drv) {
@@ -4299,16 +4301,17 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
    return true;
}

void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity)
{
    int64_t bitmap_size;

    if (enable) {
        if (!bs->dirty_bitmap) {
    assert((granularity & (granularity - 1)) == 0);

    if (granularity) {
        granularity >>= BDRV_SECTOR_BITS;
        assert(!bs->dirty_bitmap);
        bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
            bs->dirty_bitmap = hbitmap_alloc(bitmap_size,
                                             BDRV_LOG_SECTORS_PER_DIRTY_CHUNK);
        }
        bs->dirty_bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1);
    } else {
        if (bs->dirty_bitmap) {
            hbitmap_free(bs->dirty_bitmap);
+4 −10
Original line number Diff line number Diff line
@@ -17,14 +17,8 @@
#include "qemu/ratelimit.h"
#include "qemu/bitmap.h"

enum {
    /*
     * Size of data buffer for populating the image file.  This should be large
     * enough to process multiple clusters in a single call, so that populating
     * contiguous regions of the image is efficient.
     */
    BLOCK_SIZE = 512 * BDRV_SECTORS_PER_DIRTY_CHUNK, /* in bytes */
};
#define BLOCK_SIZE                       (1 << 20)
#define BDRV_SECTORS_PER_DIRTY_CHUNK     (BLOCK_SIZE >> BDRV_SECTOR_BITS)

#define SLICE_TIME 100000000ULL /* ns */

@@ -276,7 +270,7 @@ static void coroutine_fn mirror_run(void *opaque)
immediate_exit:
    qemu_vfree(s->buf);
    g_free(s->cow_bitmap);
    bdrv_set_dirty_tracking(bs, false);
    bdrv_set_dirty_tracking(bs, 0);
    bdrv_iostatus_disable(s->target);
    if (s->should_complete && ret == 0) {
        if (bdrv_get_flags(s->target) != bdrv_get_flags(s->common.bs)) {
@@ -364,7 +358,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
    s->mode = mode;
    s->buf_size = BLOCK_SIZE;

    bdrv_set_dirty_tracking(bs, true);
    bdrv_set_dirty_tracking(bs, BLOCK_SIZE);
    bdrv_set_enable_write_cache(s->target, true);
    bdrv_set_on_error(s->target, on_target_error, on_target_error);
    bdrv_iostatus_enable(s->target);
+1 −4
Original line number Diff line number Diff line
@@ -355,11 +355,8 @@ void bdrv_set_buffer_alignment(BlockDriverState *bs, int align);
void *qemu_blockalign(BlockDriverState *bs, size_t size);
bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);

#define BDRV_SECTORS_PER_DIRTY_CHUNK     (1 << BDRV_LOG_SECTORS_PER_DIRTY_CHUNK)
#define BDRV_LOG_SECTORS_PER_DIRTY_CHUNK 11

struct HBitmapIter;
void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable);
void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity);
int bdrv_get_dirty(BlockDriverState *bs, int64_t sector);
void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
+3 −1
Original line number Diff line number Diff line
@@ -667,10 +667,12 @@
#
# @count: number of dirty bytes according to the dirty bitmap
#
# @granularity: granularity of the dirty bitmap in bytes (since 1.4)
#
# Since: 1.3
##
{ 'type': 'BlockDirtyInfo',
  'data': {'count': 'int'} }
  'data': {'count': 'int', 'granularity': 'int'} }

##
# @BlockInfo: