[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 9/9] mirror: replace bdrv_dirty_bitmap with plain hb
From: |
Denis V. Lunev |
Subject: |
[Qemu-devel] [PATCH 9/9] mirror: replace bdrv_dirty_bitmap with plain hbitmap |
Date: |
Tue, 14 Jun 2016 18:25:16 +0300 |
We have replaced the mechanics of syncing new writes in the previous patch
and thus do not need to track dirty changes anymore.
Signed-off-by: Denis V. Lunev <address@hidden>
Reviewed-by: Vladimir Sementsov-Ogievskiy<address@hidden>
CC: Stefan Hajnoczi <address@hidden>
CC: Fam Zheng <address@hidden>
CC: Kevin Wolf <address@hidden>
CC: Max Reitz <address@hidden>
CC: Jeff Cody <address@hidden>
CC: Eric Blake <address@hidden>
---
block/mirror.c | 58 ++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 38 insertions(+), 20 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index 086256c..926fd13 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -52,7 +52,7 @@ typedef struct MirrorBlockJob {
size_t buf_size;
int64_t bdev_length;
unsigned long *cow_bitmap;
- BdrvDirtyBitmap *dirty_bitmap;
+ HBitmap *copy_bitmap;
HBitmapIter hbi;
uint8_t *buf;
QSIMPLEQ_HEAD(, MirrorBuffer) buf_free;
@@ -141,7 +141,7 @@ static void mirror_write_complete(void *opaque, int ret)
if (ret < 0) {
BlockErrorAction action;
- bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
+ hbitmap_set(s->copy_bitmap, op->sector_num, op->nb_sectors);
action = mirror_error_action(s, false, -ret);
if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
s->ret = ret;
@@ -157,7 +157,7 @@ static void mirror_read_complete(void *opaque, int ret)
if (ret < 0) {
BlockErrorAction action;
- bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
+ hbitmap_set(s->copy_bitmap, op->sector_num, op->nb_sectors);
action = mirror_error_action(s, true, -ret);
if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
s->ret = ret;
@@ -328,9 +328,9 @@ static uint64_t coroutine_fn
mirror_iteration(MirrorBlockJob *s)
sector_num = hbitmap_iter_next(&s->hbi);
if (sector_num < 0) {
- bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
+ hbitmap_iter_init(&s->hbi, s->copy_bitmap, 0);
sector_num = hbitmap_iter_next(&s->hbi);
- trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap));
+ trace_mirror_restart_iter(s, hbitmap_count(s->copy_bitmap));
assert(sector_num >= 0);
}
@@ -347,7 +347,7 @@ static uint64_t coroutine_fn
mirror_iteration(MirrorBlockJob *s)
int64_t next_sector = sector_num + nb_chunks * sectors_per_chunk;
int64_t next_chunk = next_sector / sectors_per_chunk;
if (next_sector >= end ||
- !bdrv_get_dirty(source, s->dirty_bitmap, next_sector)) {
+ !hbitmap_get(s->copy_bitmap, next_sector)) {
break;
}
if (test_bit(next_chunk, s->in_flight_bitmap)) {
@@ -357,7 +357,7 @@ static uint64_t coroutine_fn
mirror_iteration(MirrorBlockJob *s)
hbitmap_next = hbitmap_iter_next(&s->hbi);
if (hbitmap_next > next_sector || hbitmap_next < 0) {
/* The bitmap iterator's cache is stale, refresh it */
- bdrv_set_dirty_iter(&s->hbi, next_sector);
+ hbitmap_iter_init(&s->hbi, s->copy_bitmap, next_sector);
hbitmap_next = hbitmap_iter_next(&s->hbi);
}
assert(hbitmap_next == next_sector);
@@ -368,8 +368,7 @@ static uint64_t coroutine_fn
mirror_iteration(MirrorBlockJob *s)
* calling bdrv_get_block_status_above could yield - if some blocks are
* marked dirty in this window, we need to know.
*/
- bdrv_reset_dirty_bitmap(s->dirty_bitmap, sector_num,
- nb_chunks * sectors_per_chunk);
+ hbitmap_reset(s->copy_bitmap, sector_num, nb_chunks * sectors_per_chunk);
bitmap_set(s->in_flight_bitmap, sector_num / sectors_per_chunk, nb_chunks);
while (nb_chunks > 0 && sector_num < end) {
int ret;
@@ -553,8 +552,8 @@ static int coroutine_fn mirror_before_write_notify(
aligned_start = QEMU_ALIGN_UP(sector_num, sectors_per_chunk);
aligned_end = QEMU_ALIGN_DOWN(sector_num + nb_sectors, sectors_per_chunk);
if (aligned_end > aligned_start) {
- bdrv_reset_dirty_bitmap(s->dirty_bitmap, aligned_start,
- aligned_end - aligned_start);
+ hbitmap_reset(s->copy_bitmap, aligned_start,
+ aligned_end - aligned_start);
}
if (req->type == BDRV_TRACKED_DISCARD) {
@@ -596,7 +595,7 @@ static int mirror_dirty_init(MirrorBlockJob *s)
if (base == NULL && !bdrv_has_zero_init(target_bs) &&
target_bs->drv->bdrv_co_write_zeroes == NULL) {
- bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, end);
+ hbitmap_set(s->copy_bitmap, 0, end);
return 0;
}
@@ -625,7 +624,7 @@ static int mirror_dirty_init(MirrorBlockJob *s)
assert(n > 0);
if (ret == 1) {
- bdrv_set_dirty_bitmap(s->dirty_bitmap, sector_num, n);
+ hbitmap_set(s->copy_bitmap, sector_num, n);
}
sector_num += n;
}
@@ -729,7 +728,7 @@ static void coroutine_fn mirror_run(void *opaque)
}
last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
- bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
+ hbitmap_iter_init(&s->hbi, s->copy_bitmap, 0);
for (;;) {
uint64_t delay_ns = 0;
int64_t cnt;
@@ -740,7 +739,7 @@ static void coroutine_fn mirror_run(void *opaque)
goto immediate_exit;
}
- cnt = bdrv_get_dirty_count(s->dirty_bitmap);
+ cnt = hbitmap_count(s->copy_bitmap);
/* s->common.offset contains the number of bytes already processed so
* far, cnt is the number of dirty sectors remaining and
* s->sectors_in_flight is the number of sectors currently being
@@ -787,7 +786,7 @@ static void coroutine_fn mirror_run(void *opaque)
should_complete = s->should_complete ||
block_job_is_cancelled(&s->common);
- cnt = bdrv_get_dirty_count(s->dirty_bitmap);
+ cnt = hbitmap_count(s->copy_bitmap);
}
}
@@ -802,7 +801,7 @@ static void coroutine_fn mirror_run(void *opaque)
*/
trace_mirror_before_drain(s, cnt);
bdrv_co_drain(bs);
- cnt = bdrv_get_dirty_count(s->dirty_bitmap);
+ cnt = hbitmap_count(s->copy_bitmap);
}
ret = 0;
@@ -842,7 +841,7 @@ immediate_exit:
qemu_vfree(s->buf);
g_free(s->cow_bitmap);
g_free(s->in_flight_bitmap);
- bdrv_release_dirty_bitmap(bs, s->dirty_bitmap);
+ hbitmap_free(s->copy_bitmap);
data = g_malloc(sizeof(*data));
data->ret = ret;
@@ -925,6 +924,25 @@ static const BlockJobDriver commit_active_job_driver = {
.complete = mirror_complete,
};
+static HBitmap *mirror_create_bitmap(BlockDriverState *bs,
+ uint32_t granularity, Error **errp)
+{
+ int64_t bitmap_size;
+ uint32_t sector_granularity;
+
+ assert((granularity & (granularity - 1)) == 0);
+
+ sector_granularity = granularity >> BDRV_SECTOR_BITS;
+ assert(sector_granularity);
+ bitmap_size = bdrv_nb_sectors(bs);
+ if (bitmap_size < 0) {
+ error_setg_errno(errp, -bitmap_size, "could not get length of device");
+ errno = -bitmap_size;
+ return NULL;
+ }
+ return hbitmap_alloc(bitmap_size, ctz32(sector_granularity));
+}
+
static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
const char *replaces,
int64_t speed, uint32_t granularity,
@@ -971,8 +989,8 @@ static void mirror_start_job(BlockDriverState *bs,
BlockDriverState *target,
s->buf_size = ROUND_UP(buf_size, granularity);
s->unmap = unmap;
- s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
- if (!s->dirty_bitmap) {
+ s->copy_bitmap = mirror_create_bitmap(bs, granularity, errp);
+ if (s->copy_bitmap == NULL) {
g_free(s->replaces);
blk_unref(s->target);
block_job_unref(&s->common);
--
2.5.0
- Re: [Qemu-devel] [PATCH 6/9] block: pass qiov into before_write notifier, (continued)
- [Qemu-devel] [PATCH 7/9] mirror: allow to save buffer for QEMUIOVector in MirrorOp, Denis V. Lunev, 2016/06/14
- [Qemu-devel] [PATCH 5/9] mirror: improve performance of mirroring of empty disk, Denis V. Lunev, 2016/06/14
- Re: [Qemu-devel] [PATCH 5/9] mirror: improve performance of mirroring of empty disk, Eric Blake, 2016/06/14
- Re: [Qemu-devel] [PATCH 5/9] mirror: improve performance of mirroring of empty disk, Stefan Hajnoczi, 2016/06/15
- Re: [Qemu-devel] [PATCH 5/9] mirror: improve performance of mirroring of empty disk, Denis V. Lunev, 2016/06/15
- Re: [Qemu-devel] [PATCH 5/9] mirror: improve performance of mirroring of empty disk, Stefan Hajnoczi, 2016/06/16
- Re: [Qemu-devel] [PATCH 5/9] mirror: improve performance of mirroring of empty disk, Eric Blake, 2016/06/16
- Re: [Qemu-devel] [PATCH 5/9] mirror: improve performance of mirroring of empty disk, Stefan Hajnoczi, 2016/06/17
[Qemu-devel] [PATCH 9/9] mirror: replace bdrv_dirty_bitmap with plain hbitmap,
Denis V. Lunev <=
[Qemu-devel] [PATCH 8/9] mirror: use synch scheme for drive mirror, Denis V. Lunev, 2016/06/14
Re: [Qemu-devel] [PATCH 0/9] major rework of drive-mirror, Kevin Wolf, 2016/06/15
Re: [Qemu-devel] [PATCH 0/9] major rework of drive-mirror, Stefan Hajnoczi, 2016/06/15
Re: [Qemu-devel] [PATCH 0/9] major rework of drive-mirror, Dr. David Alan Gilbert, 2016/06/15