[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 27/38] block/parallels: improve image writing perform
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PULL 27/38] block/parallels: improve image writing performance further |
Date: |
Fri, 22 May 2015 10:01:59 +0100 |
From: "Denis V. Lunev" <address@hidden>
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 <address@hidden>
Reviewed-by: Roman Kagan <address@hidden>
Signed-off-by: Roman Kagan <address@hidden>
Message-id: address@hidden
CC: Kevin Wolf <address@hidden>
CC: Stefan Hajnoczi <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
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
- [Qemu-devel] [PULL 15/38] block/parallels: create bat2sect helper, (continued)
- [Qemu-devel] [PULL 15/38] block/parallels: create bat2sect helper, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 19/38] block/parallels: implement parallels_check method of block driver, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 17/38] block/parallels: read parallels image header and BAT into single buffer, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 20/38] block/parallels: implement incorrect close detection, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 21/38] iotests, parallels: check for incorrectly closed image in tests, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 24/38] block/parallels: delay writing to BAT till bdrv_co_flush_to_os, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 22/38] block/parallels: improve image reading performance, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 23/38] block/parallels: create bat_entry_off helper, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 26/38] block/parallels: optimize linear image expansion, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 28/38] configure: handle clang -nopie argument warning, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 27/38] block/parallels: improve image writing performance further,
Stefan Hajnoczi <=
- [Qemu-devel] [PULL 29/38] configure: factor out supported flag check, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 25/38] block/parallels: add prealloc-mode and prealloc-size open paramemets, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 30/38] configure: silence glib unknown attribute __alloc_size__, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 31/38] configure: Add workaround for ccache and clang, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 33/38] block: minimal bounce buffer alignment, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 34/38] block: align bounce buffers to page, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 35/38] Revert "block: Fix unaligned zero write", Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 32/38] block: return EPERM on writes or discards to read-only devices, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 38/38] block: get_block_status: use "else" when testing the opposite condition, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 37/38] qemu-iotests: Test unaligned sub-block zero write, Stefan Hajnoczi, 2015/05/22