From patchwork Tue Mar 10 08:51:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 448420 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C7A671401AA for ; Tue, 10 Mar 2015 19:57:16 +1100 (AEDT) Received: from localhost ([::1]:47322 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YVFyV-0002fp-1U for incoming@patchwork.ozlabs.org; Tue, 10 Mar 2015 04:57:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51718) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YVFsW-0007dg-L4 for qemu-devel@nongnu.org; Tue, 10 Mar 2015 04:51:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YVFsQ-0007nX-48 for qemu-devel@nongnu.org; Tue, 10 Mar 2015 04:51:04 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:41055 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YVFsP-0007iy-LX for qemu-devel@nongnu.org; Tue, 10 Mar 2015 04:50:57 -0400 Received: from hades.sw.ru ([10.30.8.132]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id t2A8olBC017896; Tue, 10 Mar 2015 11:50:49 +0300 (MSK) From: "Denis V. Lunev" To: Date: Tue, 10 Mar 2015 11:51:21 +0300 Message-Id: <1425977481-13317-28-git-send-email-den@openvz.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1425977481-13317-1-git-send-email-den@openvz.org> References: <1425977481-13317-1-git-send-email-den@openvz.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.0 [fuzzy] X-Received-From: 195.214.232.25 Cc: Kevin Wolf , "Denis V. Lunev" , qemu-devel@nongnu.org, Stefan Hajnoczi , Roman Kagan Subject: [Qemu-devel] [PATCH 27/27] block/parallels: improve image writing performance further X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 Gb/sec to 235 Gb/sec on my SSD HDD. Signed-off-by: Denis V. Lunev CC: Roman Kagan CC: Kevin Wolf CC: Stefan Hajnoczi Reviewed-by: Roman Kagan --- block/parallels.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/block/parallels.c b/block/parallels.c index c6343c5..ccfdfab 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -178,42 +178,46 @@ 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; - idx = sector_num / s->tracks; - offset = sector_num % s->tracks; + pos = block_status(s, sector_num, nb_sectors, pnum); + if (pos > 0) { + return pos; + } + idx = 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; } @@ -278,8 +282,8 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs, qemu_co_mutex_lock(&s->lock); while (nb_sectors > 0) { - int64_t position = allocate_cluster(bs, sector_num); - int n = cluster_remainder(s, sector_num, nb_sectors); + int n; + int64_t position = allocate_clusters(bs, sector_num, nb_sectors, &n); int nbytes = n << BDRV_SECTOR_BITS; if (position < 0) {