From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57013) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YvirL-0004oa-9z for qemu-devel@nongnu.org; Fri, 22 May 2015 05:03:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YvirK-0004zB-8r for qemu-devel@nongnu.org; Fri, 22 May 2015 05:03:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37276) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YvirK-0004yy-1z for qemu-devel@nongnu.org; Fri, 22 May 2015 05:03:14 -0400 From: Stefan Hajnoczi Date: Fri, 22 May 2015 10:01:59 +0100 Message-Id: <1432285330-13994-28-git-send-email-stefanha@redhat.com> In-Reply-To: <1432285330-13994-1-git-send-email-stefanha@redhat.com> References: <1432285330-13994-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [PULL 27/38] block/parallels: improve image writing performance further List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Peter Maydell , Roman Kagan , Stefan Hajnoczi , "Denis V. Lunev" From: "Denis V. Lunev" Try to perform IO for the biggest continuous block possible. All blocks abscent in the image are accounted in the same type and preallocation is made for all of them at once. The performance for sequential write is increased from 200 Mb/sec to 235 Mb/sec on my SSD HDD. Signed-off-by: Denis V. Lunev Reviewed-by: Roman Kagan Signed-off-by: Roman Kagan Message-id: 1430207220-24458-28-git-send-email-den@openvz.org CC: Kevin Wolf CC: Stefan Hajnoczi Signed-off-by: Stefan Hajnoczi --- block/parallels.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/block/parallels.c b/block/parallels.c index e7124d9..046b568 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -183,43 +183,47 @@ static int64_t block_status(BDRVParallelsState *s, int64_t sector_num, return start_off; } -static int64_t allocate_cluster(BlockDriverState *bs, int64_t sector_num) +static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, int *pnum) { BDRVParallelsState *s = bs->opaque; - uint32_t idx, offset; - int64_t pos; + uint32_t idx, to_allocate, i; + int64_t pos, space; + + pos = block_status(s, sector_num, nb_sectors, pnum); + if (pos > 0) { + return pos; + } idx = sector_num / s->tracks; - offset = sector_num % s->tracks; - if (idx >= s->bat_size) { return -EINVAL; } - if (s->bat_bitmap[idx] != 0) { - return bat2sect(s, idx) + offset; - } - pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS; - if (s->data_end + s->tracks > pos) { + to_allocate = (sector_num + *pnum + s->tracks - 1) / s->tracks - idx; + space = to_allocate * s->tracks; + if (s->data_end + space > bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS) { int ret; + space += s->prealloc_size; if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) { - ret = bdrv_write_zeroes(bs->file, s->data_end, - s->prealloc_size, 0); + ret = bdrv_write_zeroes(bs->file, s->data_end, space, 0); } else { ret = bdrv_truncate(bs->file, - (s->data_end + s->prealloc_size) << BDRV_SECTOR_BITS); + (s->data_end + space) << BDRV_SECTOR_BITS); } if (ret < 0) { return ret; } } - pos = s->data_end; - s->data_end += s->tracks; - s->bat_bitmap[idx] = cpu_to_le32(pos / s->off_multiplier); + for (i = 0; i < to_allocate; i++) { + s->bat_bitmap[idx + i] = cpu_to_le32(s->data_end / s->off_multiplier); + s->data_end += s->tracks; + bitmap_set(s->bat_dirty_bmap, + bat_entry_off(idx) / s->bat_dirty_block, 1); + } - bitmap_set(s->bat_dirty_bmap, bat_entry_off(idx) / s->bat_dirty_block, 1); - return bat2sect(s, idx) + offset; + return bat2sect(s, idx) + sector_num % s->tracks; } @@ -287,14 +291,13 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs, int n, nbytes; qemu_co_mutex_lock(&s->lock); - position = allocate_cluster(bs, sector_num); + position = allocate_clusters(bs, sector_num, nb_sectors, &n); qemu_co_mutex_unlock(&s->lock); if (position < 0) { ret = (int)position; break; } - n = cluster_remainder(s, sector_num, nb_sectors); nbytes = n << BDRV_SECTOR_BITS; qemu_iovec_reset(&hd_qiov); -- 2.1.0