[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 27/27] block/parallels: improve image writing perfor
From: |
Denis V. Lunev |
Subject: |
[Qemu-devel] [PATCH 27/27] block/parallels: improve image writing performance further |
Date: |
Wed, 11 Mar 2015 13:28:21 +0300 |
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 <address@hidden>
Reviewed-by: Roman Kagan <address@hidden>
CC: Kevin Wolf <address@hidden>
CC: Stefan Hajnoczi <address@hidden>
---
block/parallels.c | 44 ++++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index 2a1e31f..7531340 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -179,43 +179,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;
- 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;
}
@@ -280,8 +284,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) {
--
1.9.1
- Re: [Qemu-devel] [PATCH 21/27] block/parallels: no need to flush on each block allocation table update, (continued)
- [Qemu-devel] [PATCH 02/27] block/parallels: rename parallels_header to ParallelsHeader, Denis V. Lunev, 2015/03/10
- [Qemu-devel] [PATCH v3 0/27] write/create for Parallels images with reasonable performance, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 22/27] block/parallels: improve image reading performance, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 05/27] block/parallels: add get_block_status, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 01/27] iotests, parallels: quote TEST_IMG in 076 test to be path-safe, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 03/27] block/parallels: switch to bdrv_read, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 24/27] block/parallels: delay writing to BAT till bdrv_co_flush_to_os, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 13/27] block/parallels: rename catalog_ names to bat_, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 10/27] block/parallels: support parallels image creation, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 27/27] block/parallels: improve image writing performance further,
Denis V. Lunev <=
- [Qemu-devel] [PATCH 19/27] block/parallels: implement incorrect close detection, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 11/27] iotests, parallels: test for newly created parallels image via qemu-img, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 15/27] block/parallels: keep BAT bitmap data in little endian in memory, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 18/27] block/parallels: implement parallels_check method of block driver, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 21/27] block/parallels: no need to flush on each block allocation table update, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 08/27] block/parallels: _co_writev callback for Parallels format, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 12/27] parallels: change copyright information in the image header, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 04/27] block/parallels: read up to cluster end in one go, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 14/27] block/parallels: create bat2sect helper, Denis V. Lunev, 2015/03/11