[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 05/23] block migration: Cleanup dirty tracking code
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH 05/23] block migration: Cleanup dirty tracking code |
Date: |
Mon, 30 Nov 2009 18:21:20 +0100 |
User-agent: |
StGIT/0.14.3 |
This switches the dirty bitmap to a true bitmap, reducing its footprint
(specifically in caches). It moreover fixes off-by-one bugs in
set_dirty_bitmap (nb_sectors+1 were marked) and bdrv_get_dirty (limit
check allowed one sector behind end of drive). And is drops redundant
dirty_tracking field from BlockDriverState.
Signed-off-by: Jan Kiszka <address@hidden>
---
block.c | 44 ++++++++++++++++++++++++--------------------
block_int.h | 3 +--
2 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/block.c b/block.c
index 9ce6d8a..853f025 100644
--- a/block.c
+++ b/block.c
@@ -642,12 +642,21 @@ static void set_dirty_bitmap(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, int dirty)
{
int64_t start, end;
+ unsigned long val, idx, bit;
start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
- end = (sector_num + nb_sectors) / BDRV_SECTORS_PER_DIRTY_CHUNK;
+ end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
for (; start <= end; start++) {
- bs->dirty_bitmap[start] = dirty;
+ idx = start / (sizeof(unsigned long) * 8);
+ bit = start % (sizeof(unsigned long) * 8);
+ val = bs->dirty_bitmap[idx];
+ if (dirty) {
+ val |= 1 << bit;
+ } else {
+ val &= ~(1 << bit);
+ }
+ bs->dirty_bitmap[idx] = val;
}
}
@@ -668,7 +677,7 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO;
- if (bs->dirty_tracking) {
+ if (bs->dirty_bitmap) {
set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
}
@@ -1218,7 +1227,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t
sector_num,
if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO;
- if (bs->dirty_tracking) {
+ if (bs->dirty_bitmap) {
set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
}
@@ -1419,7 +1428,7 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs,
int64_t sector_num,
if (bdrv_check_request(bs, sector_num, nb_sectors))
return NULL;
- if (bs->dirty_tracking) {
+ if (bs->dirty_bitmap) {
set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
}
@@ -1965,23 +1974,17 @@ void bdrv_set_dirty_tracking(BlockDriverState *bs, int
enable)
int64_t bitmap_size;
if (enable) {
- if (bs->dirty_tracking == 0) {
- int64_t i;
- uint8_t test;
-
- bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
- bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK;
- bitmap_size++;
+ if (!bs->dirty_bitmap) {
+ bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
+ BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
+ bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
bs->dirty_bitmap = qemu_mallocz(bitmap_size);
-
- bs->dirty_tracking = enable;
- for(i = 0; i < bitmap_size; i++) test = bs->dirty_bitmap[i];
}
} else {
- if (bs->dirty_tracking != 0) {
+ if (bs->dirty_bitmap) {
qemu_free(bs->dirty_bitmap);
- bs->dirty_tracking = enable;
+ bs->dirty_bitmap = NULL;
}
}
}
@@ -1990,9 +1993,10 @@ int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
{
int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
- if (bs->dirty_bitmap != NULL &&
- (sector << BDRV_SECTOR_BITS) <= bdrv_getlength(bs)) {
- return bs->dirty_bitmap[chunk];
+ if (bs->dirty_bitmap &&
+ (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
+ return bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
+ (1 << (chunk % (sizeof(unsigned long) * 8)));
} else {
return 0;
}
diff --git a/block_int.h b/block_int.h
index 7ebe926..907e864 100644
--- a/block_int.h
+++ b/block_int.h
@@ -168,8 +168,7 @@ struct BlockDriverState {
int cyls, heads, secs, translation;
int type;
char device_name[32];
- int dirty_tracking;
- uint8_t *dirty_bitmap;
+ unsigned long *dirty_bitmap;
BlockDriverState *next;
void *private;
};
- [Qemu-devel] [PATCH 00/23] block migration: Fixes, cleanups and speedups, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 13/23] block migration: Consolidate mig_read_device_bulk into mig_save_device_bulk, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 02/23] migration: Catch multiple start commands, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 23/23] block migration: Increase dirty chunk size to 1M, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 16/23] ram migration: Stop loading on error, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 05/23] block migration: Cleanup dirty tracking code,
Jan Kiszka <=
- [Qemu-devel] [PATCH 06/23] block migration: Avoid large stack buffer, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 19/23] live migration: Propagate output monitor to callback handler, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 21/23] block migration: Report progress also via info migration, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 01/23] migration: Fix use of file after release, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 08/23] block migration: Drop dead code, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 17/23] live migration: Allow cleanup after cancellation or error, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 03/23] block migration: Fix coding style and whitespaces, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 15/23] block migration: Add error handling/propagation, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 12/23] block migration: Clean up use of total_sectors, Jan Kiszka, 2009/11/30
- [Qemu-devel] [PATCH 14/23] block migration: Consolidate block transmission, Jan Kiszka, 2009/11/30