mirror of https://github.com/xemu-project/xemu.git
block: allow customizing the granularity of the dirty bitmap
Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
acc906c6c5
commit
50717e941b
|
@ -23,7 +23,8 @@
|
||||||
#include "sysemu/blockdev.h"
|
#include "sysemu/blockdev.h"
|
||||||
#include <assert.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_DEVICE_BLOCK 0x01
|
||||||
#define BLK_MIG_FLAG_EOS 0x02
|
#define BLK_MIG_FLAG_EOS 0x02
|
||||||
|
@ -254,7 +255,7 @@ static void set_dirty_tracking(int enable)
|
||||||
BlkMigDevState *bmds;
|
BlkMigDevState *bmds;
|
||||||
|
|
||||||
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
block.c
17
block.c
|
@ -2833,6 +2833,8 @@ BlockInfo *bdrv_query_info(BlockDriverState *bs)
|
||||||
info->has_dirty = true;
|
info->has_dirty = true;
|
||||||
info->dirty = g_malloc0(sizeof(*info->dirty));
|
info->dirty = g_malloc0(sizeof(*info->dirty));
|
||||||
info->dirty->count = bdrv_get_dirty_count(bs) * BDRV_SECTOR_SIZE;
|
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) {
|
if (bs->drv) {
|
||||||
|
@ -4299,16 +4301,17 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
|
void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity)
|
||||||
{
|
{
|
||||||
int64_t bitmap_size;
|
int64_t bitmap_size;
|
||||||
|
|
||||||
if (enable) {
|
assert((granularity & (granularity - 1)) == 0);
|
||||||
if (!bs->dirty_bitmap) {
|
|
||||||
bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
|
if (granularity) {
|
||||||
bs->dirty_bitmap = hbitmap_alloc(bitmap_size,
|
granularity >>= BDRV_SECTOR_BITS;
|
||||||
BDRV_LOG_SECTORS_PER_DIRTY_CHUNK);
|
assert(!bs->dirty_bitmap);
|
||||||
}
|
bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
|
||||||
|
bs->dirty_bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1);
|
||||||
} else {
|
} else {
|
||||||
if (bs->dirty_bitmap) {
|
if (bs->dirty_bitmap) {
|
||||||
hbitmap_free(bs->dirty_bitmap);
|
hbitmap_free(bs->dirty_bitmap);
|
||||||
|
|
|
@ -17,14 +17,8 @@
|
||||||
#include "qemu/ratelimit.h"
|
#include "qemu/ratelimit.h"
|
||||||
#include "qemu/bitmap.h"
|
#include "qemu/bitmap.h"
|
||||||
|
|
||||||
enum {
|
#define BLOCK_SIZE (1 << 20)
|
||||||
/*
|
#define BDRV_SECTORS_PER_DIRTY_CHUNK (BLOCK_SIZE >> BDRV_SECTOR_BITS)
|
||||||
* 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 SLICE_TIME 100000000ULL /* ns */
|
#define SLICE_TIME 100000000ULL /* ns */
|
||||||
|
|
||||||
|
@ -276,7 +270,7 @@ static void coroutine_fn mirror_run(void *opaque)
|
||||||
immediate_exit:
|
immediate_exit:
|
||||||
qemu_vfree(s->buf);
|
qemu_vfree(s->buf);
|
||||||
g_free(s->cow_bitmap);
|
g_free(s->cow_bitmap);
|
||||||
bdrv_set_dirty_tracking(bs, false);
|
bdrv_set_dirty_tracking(bs, 0);
|
||||||
bdrv_iostatus_disable(s->target);
|
bdrv_iostatus_disable(s->target);
|
||||||
if (s->should_complete && ret == 0) {
|
if (s->should_complete && ret == 0) {
|
||||||
if (bdrv_get_flags(s->target) != bdrv_get_flags(s->common.bs)) {
|
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->mode = mode;
|
||||||
s->buf_size = BLOCK_SIZE;
|
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_enable_write_cache(s->target, true);
|
||||||
bdrv_set_on_error(s->target, on_target_error, on_target_error);
|
bdrv_set_on_error(s->target, on_target_error, on_target_error);
|
||||||
bdrv_iostatus_enable(s->target);
|
bdrv_iostatus_enable(s->target);
|
||||||
|
|
|
@ -355,11 +355,8 @@ void bdrv_set_buffer_alignment(BlockDriverState *bs, int align);
|
||||||
void *qemu_blockalign(BlockDriverState *bs, size_t size);
|
void *qemu_blockalign(BlockDriverState *bs, size_t size);
|
||||||
bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
|
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;
|
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);
|
int bdrv_get_dirty(BlockDriverState *bs, int64_t sector);
|
||||||
void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
|
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);
|
void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
|
||||||
|
|
|
@ -667,10 +667,12 @@
|
||||||
#
|
#
|
||||||
# @count: number of dirty bytes according to the dirty bitmap
|
# @count: number of dirty bytes according to the dirty bitmap
|
||||||
#
|
#
|
||||||
|
# @granularity: granularity of the dirty bitmap in bytes (since 1.4)
|
||||||
|
#
|
||||||
# Since: 1.3
|
# Since: 1.3
|
||||||
##
|
##
|
||||||
{ 'type': 'BlockDirtyInfo',
|
{ 'type': 'BlockDirtyInfo',
|
||||||
'data': {'count': 'int'} }
|
'data': {'count': 'int', 'granularity': 'int'} }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @BlockInfo:
|
# @BlockInfo:
|
||||||
|
|
Loading…
Reference in New Issue