From patchwork Mon Nov 30 17:21:20 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 39826 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9B6311007D2 for ; Tue, 1 Dec 2009 04:54:04 +1100 (EST) Received: from localhost ([127.0.0.1]:40689 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NFARl-0002JC-If for incoming@patchwork.ozlabs.org; Mon, 30 Nov 2009 12:54:01 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NFA2h-0003oS-RW for qemu-devel@nongnu.org; Mon, 30 Nov 2009 12:28:07 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NFA2X-0003hs-MA for qemu-devel@nongnu.org; Mon, 30 Nov 2009 12:28:02 -0500 Received: from [199.232.76.173] (port=36079 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NFA2X-0003hi-GE for qemu-devel@nongnu.org; Mon, 30 Nov 2009 12:27:57 -0500 Received: from thoth.sbs.de ([192.35.17.2]:20217) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1NFA2V-0004fe-MC for qemu-devel@nongnu.org; Mon, 30 Nov 2009 12:27:56 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by thoth.sbs.de (8.12.11.20060308/8.12.11) with ESMTP id nAUHRpNV018728; Mon, 30 Nov 2009 18:27:51 +0100 Received: from [139.25.109.167] (mchn012c.ww002.siemens.net [139.25.109.167] (may be forged)) by mail1.siemens.de (8.12.11.20060308/8.12.11) with ESMTP id nAUHRoOL001967; Mon, 30 Nov 2009 18:27:50 +0100 Resent-From: Jan Kiszka Resent-To: Anthony Liguori Resent-Cc: qemu-devel , Liran Schour , Pierre Riteau Resent-Date: Mon, 30 Nov 2009 18:27:50 +0100 Resent-Message-Id: <4B140096.9070905@siemens.com> Resent-User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 From: Jan Kiszka To: Anthony Liguori Date: Mon, 30 Nov 2009 18:21:20 +0100 Message-ID: <20091130172119.22889.71552.stgit@mchn012c.ww002.siemens.net> In-Reply-To: <20091130172119.22889.28114.stgit@mchn012c.ww002.siemens.net> References: <20091130172119.22889.28114.stgit@mchn012c.ww002.siemens.net> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.4-2.6 Resent-Date: Mon, 30 Nov 2009 12:28:01 -0500 Cc: qemu-devel@nongnu.org, Liran Schour , Pierre Riteau Subject: [Qemu-devel] [PATCH 05/23] block migration: Cleanup dirty tracking code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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; };