07d2889ef8
Update to v2.6.1 stable release. OBS-URL: https://build.opensuse.org/request/show/419833 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=311
105 lines
3.7 KiB
Diff
105 lines
3.7 KiB
Diff
From c9f5c5004b9fb97398c8dc0003303493904c986c Mon Sep 17 00:00:00 2001
|
|
From: "Denis V. Lunev" <den@openvz.org>
|
|
Date: Thu, 2 Jun 2016 18:58:15 +0300
|
|
Subject: [PATCH] qcow2: avoid extra flushes in qcow2
|
|
|
|
The problem with excessive flushing was found by a couple of performance
|
|
tests:
|
|
- parallel directory tree creation (from 2 processes)
|
|
- 32 cached writes + fsync at the end in a loop
|
|
|
|
For the first one results improved from 2.6 loops/sec to 3.5 loops/sec.
|
|
Each loop creates 10^3 directories with 10 files in each.
|
|
|
|
For the second one results improved from ~600 fsync/sec to ~1100
|
|
fsync/sec. Though, it was run on SSD so it probably won't show such
|
|
performance gain on rotational media.
|
|
|
|
qcow2_cache_flush() calls bdrv_flush() unconditionally after writing
|
|
cache entries of a particular cache. This can lead to as many as
|
|
2 additional fdatasyncs inside bdrv_flush.
|
|
|
|
We can simply skip all fdatasync calls inside qcow2_co_flush_to_os
|
|
as bdrv_flush for sure will do the job. These flushes are necessary to
|
|
keep the right order of writes to the different caches. Though this is
|
|
not necessary in the current code base as this ordering is ensured through
|
|
the flush in qcow2_cache_flush_dependency().
|
|
|
|
Signed-off-by: Denis V. Lunev <den@openvz.org>
|
|
CC: Pavel Borzenkov <pborzenkov@virtuozzo.com>
|
|
CC: Kevin Wolf <kwolf@redhat.com>
|
|
CC: Max Reitz <mreitz@redhat.com>
|
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
(cherry picked from commit f3c3b87dae44ac6c82246ceb3953793951800a9a)
|
|
[BR: BSC#991296]
|
|
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
|
---
|
|
block/qcow2-cache.c | 11 +++++++++--
|
|
block/qcow2.c | 4 ++--
|
|
block/qcow2.h | 1 +
|
|
3 files changed, 12 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
|
|
index 0fe8eda..208a060 100644
|
|
--- a/block/qcow2-cache.c
|
|
+++ b/block/qcow2-cache.c
|
|
@@ -226,7 +226,7 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
|
|
return 0;
|
|
}
|
|
|
|
-int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
|
|
+int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c)
|
|
{
|
|
BDRVQcow2State *s = bs->opaque;
|
|
int result = 0;
|
|
@@ -242,8 +242,15 @@ int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
|
|
}
|
|
}
|
|
|
|
+ return result;
|
|
+}
|
|
+
|
|
+int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
|
|
+{
|
|
+ int result = qcow2_cache_write(bs, c);
|
|
+
|
|
if (result == 0) {
|
|
- ret = bdrv_flush(bs->file->bs);
|
|
+ int ret = bdrv_flush(bs->file->bs);
|
|
if (ret < 0) {
|
|
result = ret;
|
|
}
|
|
diff --git a/block/qcow2.c b/block/qcow2.c
|
|
index 470734b..dc609a1 100644
|
|
--- a/block/qcow2.c
|
|
+++ b/block/qcow2.c
|
|
@@ -2774,14 +2774,14 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
|
|
int ret;
|
|
|
|
qemu_co_mutex_lock(&s->lock);
|
|
- ret = qcow2_cache_flush(bs, s->l2_table_cache);
|
|
+ ret = qcow2_cache_write(bs, s->l2_table_cache);
|
|
if (ret < 0) {
|
|
qemu_co_mutex_unlock(&s->lock);
|
|
return ret;
|
|
}
|
|
|
|
if (qcow2_need_accurate_refcounts(s)) {
|
|
- ret = qcow2_cache_flush(bs, s->refcount_block_cache);
|
|
+ ret = qcow2_cache_write(bs, s->refcount_block_cache);
|
|
if (ret < 0) {
|
|
qemu_co_mutex_unlock(&s->lock);
|
|
return ret;
|
|
diff --git a/block/qcow2.h b/block/qcow2.h
|
|
index a063a3c..7db9795 100644
|
|
--- a/block/qcow2.h
|
|
+++ b/block/qcow2.h
|
|
@@ -583,6 +583,7 @@ int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
|
|
void qcow2_cache_entry_mark_dirty(BlockDriverState *bs, Qcow2Cache *c,
|
|
void *table);
|
|
int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
|
|
+int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c);
|
|
int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
|
|
Qcow2Cache *dependency);
|
|
void qcow2_cache_depends_on_flush(Qcow2Cache *c);
|