|
|
7711c0 |
From f212cada55593c16cbfdfce2eee75ccd7b375e38 Mon Sep 17 00:00:00 2001
|
|
|
7711c0 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
7711c0 |
Date: Tue, 19 Feb 2019 17:00:11 +0100
|
|
|
7711c0 |
Subject: [PATCH 10/23] qcow2: Give the refcount cache the minimum possible
|
|
|
7711c0 |
size by default
|
|
|
7711c0 |
|
|
|
7711c0 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
7711c0 |
Message-id: <20190219170023.27826-2-kwolf@redhat.com>
|
|
|
7711c0 |
Patchwork-id: 84541
|
|
|
7711c0 |
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 01/13] qcow2: Give the refcount cache the minimum possible size by default
|
|
|
7711c0 |
Bugzilla: 1656913
|
|
|
7711c0 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
7711c0 |
|
|
|
7711c0 |
From: Alberto Garcia <berto@igalia.com>
|
|
|
7711c0 |
|
|
|
7711c0 |
The L2 and refcount caches have default sizes that can be overridden
|
|
|
7711c0 |
using the l2-cache-size and refcount-cache-size (an additional
|
|
|
7711c0 |
parameter named cache-size sets the combined size of both caches).
|
|
|
7711c0 |
|
|
|
7711c0 |
Unless forced by one of the aforementioned parameters, QEMU will set
|
|
|
7711c0 |
the unspecified sizes so that the L2 cache is 4 times larger than the
|
|
|
7711c0 |
refcount cache.
|
|
|
7711c0 |
|
|
|
7711c0 |
This is based on the premise that the refcount metadata needs to be
|
|
|
7711c0 |
only a fourth of the L2 metadata to cover the same amount of disk
|
|
|
7711c0 |
space. This is incorrect for two reasons:
|
|
|
7711c0 |
|
|
|
7711c0 |
a) The amount of disk covered by an L2 table depends solely on the
|
|
|
7711c0 |
cluster size, but in the case of a refcount block it depends on
|
|
|
7711c0 |
the cluster size *and* the width of each refcount entry.
|
|
|
7711c0 |
The 4/1 ratio is only valid with 16-bit entries (the default).
|
|
|
7711c0 |
|
|
|
7711c0 |
b) When we talk about disk space and L2 tables we are talking about
|
|
|
7711c0 |
guest space (L2 tables map guest clusters to host clusters),
|
|
|
7711c0 |
whereas refcount blocks are used for host clusters (including
|
|
|
7711c0 |
L1/L2 tables and the refcount blocks themselves). On a fully
|
|
|
7711c0 |
populated (and uncompressed) qcow2 file, image size > virtual size
|
|
|
7711c0 |
so there are more refcount entries than L2 entries.
|
|
|
7711c0 |
|
|
|
7711c0 |
Problem (a) could be fixed by adjusting the algorithm to take into
|
|
|
7711c0 |
account the refcount entry width. Problem (b) could be fixed by
|
|
|
7711c0 |
increasing a bit the refcount cache size to account for the clusters
|
|
|
7711c0 |
used for qcow2 metadata.
|
|
|
7711c0 |
|
|
|
7711c0 |
However this patch takes a completely different approach and instead
|
|
|
7711c0 |
of keeping a ratio between both cache sizes it assigns as much as
|
|
|
7711c0 |
possible to the L2 cache and the remainder to the refcount cache.
|
|
|
7711c0 |
|
|
|
7711c0 |
The reason is that L2 tables are used for every single I/O request
|
|
|
7711c0 |
from the guest and the effect of increasing the cache is significant
|
|
|
7711c0 |
and clearly measurable. Refcount blocks are however only used for
|
|
|
7711c0 |
cluster allocation and internal snapshots and in practice are accessed
|
|
|
7711c0 |
sequentially in most cases, so the effect of increasing the cache is
|
|
|
7711c0 |
negligible (even when doing random writes from the guest).
|
|
|
7711c0 |
|
|
|
7711c0 |
So, make the refcount cache as small as possible unless the user
|
|
|
7711c0 |
explicitly asks for a larger one.
|
|
|
7711c0 |
|
|
|
7711c0 |
Signed-off-by: Alberto Garcia <berto@igalia.com>
|
|
|
7711c0 |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
7711c0 |
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
|
|
7711c0 |
Message-id: 9695182c2eb11b77cb319689a1ebaa4e7c9d6591.1523968389.git.berto@igalia.com
|
|
|
7711c0 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
7711c0 |
(cherry picked from commit 52253998ec3e523c9e20ae81e2a6431d8ff733ba)
|
|
|
7711c0 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
7711c0 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
7711c0 |
---
|
|
|
7711c0 |
block/qcow2.c | 31 +++++++++++++++++++------------
|
|
|
7711c0 |
block/qcow2.h | 4 ----
|
|
|
7711c0 |
tests/qemu-iotests/137.out | 2 +-
|
|
|
7711c0 |
3 files changed, 20 insertions(+), 17 deletions(-)
|
|
|
7711c0 |
|
|
|
7711c0 |
diff --git a/block/qcow2.c b/block/qcow2.c
|
|
|
7711c0 |
index 36d1152..4b65e4c 100644
|
|
|
7711c0 |
--- a/block/qcow2.c
|
|
|
7711c0 |
+++ b/block/qcow2.c
|
|
|
7711c0 |
@@ -809,23 +809,30 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
|
|
|
7711c0 |
} else if (refcount_cache_size_set) {
|
|
|
7711c0 |
*l2_cache_size = combined_cache_size - *refcount_cache_size;
|
|
|
7711c0 |
} else {
|
|
|
7711c0 |
- *refcount_cache_size = combined_cache_size
|
|
|
7711c0 |
- / (DEFAULT_L2_REFCOUNT_SIZE_RATIO + 1);
|
|
|
7711c0 |
- *l2_cache_size = combined_cache_size - *refcount_cache_size;
|
|
|
7711c0 |
+ uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
|
|
|
7711c0 |
+ uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
|
|
|
7711c0 |
+ uint64_t min_refcount_cache =
|
|
|
7711c0 |
+ (uint64_t) MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ /* Assign as much memory as possible to the L2 cache, and
|
|
|
7711c0 |
+ * use the remainder for the refcount cache */
|
|
|
7711c0 |
+ if (combined_cache_size >= max_l2_cache + min_refcount_cache) {
|
|
|
7711c0 |
+ *l2_cache_size = max_l2_cache;
|
|
|
7711c0 |
+ *refcount_cache_size = combined_cache_size - *l2_cache_size;
|
|
|
7711c0 |
+ } else {
|
|
|
7711c0 |
+ *refcount_cache_size =
|
|
|
7711c0 |
+ MIN(combined_cache_size, min_refcount_cache);
|
|
|
7711c0 |
+ *l2_cache_size = combined_cache_size - *refcount_cache_size;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
}
|
|
|
7711c0 |
} else {
|
|
|
7711c0 |
- if (!l2_cache_size_set && !refcount_cache_size_set) {
|
|
|
7711c0 |
+ if (!l2_cache_size_set) {
|
|
|
7711c0 |
*l2_cache_size = MAX(DEFAULT_L2_CACHE_BYTE_SIZE,
|
|
|
7711c0 |
(uint64_t)DEFAULT_L2_CACHE_CLUSTERS
|
|
|
7711c0 |
* s->cluster_size);
|
|
|
7711c0 |
- *refcount_cache_size = *l2_cache_size
|
|
|
7711c0 |
- / DEFAULT_L2_REFCOUNT_SIZE_RATIO;
|
|
|
7711c0 |
- } else if (!l2_cache_size_set) {
|
|
|
7711c0 |
- *l2_cache_size = *refcount_cache_size
|
|
|
7711c0 |
- * DEFAULT_L2_REFCOUNT_SIZE_RATIO;
|
|
|
7711c0 |
- } else if (!refcount_cache_size_set) {
|
|
|
7711c0 |
- *refcount_cache_size = *l2_cache_size
|
|
|
7711c0 |
- / DEFAULT_L2_REFCOUNT_SIZE_RATIO;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+ if (!refcount_cache_size_set) {
|
|
|
7711c0 |
+ *refcount_cache_size = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
diff --git a/block/qcow2.h b/block/qcow2.h
|
|
|
7711c0 |
index 43163b2..3d92cdb 100644
|
|
|
7711c0 |
--- a/block/qcow2.h
|
|
|
7711c0 |
+++ b/block/qcow2.h
|
|
|
7711c0 |
@@ -77,10 +77,6 @@
|
|
|
7711c0 |
#define DEFAULT_L2_CACHE_CLUSTERS 8 /* clusters */
|
|
|
7711c0 |
#define DEFAULT_L2_CACHE_BYTE_SIZE 1048576 /* bytes */
|
|
|
7711c0 |
|
|
|
7711c0 |
-/* The refblock cache needs only a fourth of the L2 cache size to cover as many
|
|
|
7711c0 |
- * clusters */
|
|
|
7711c0 |
-#define DEFAULT_L2_REFCOUNT_SIZE_RATIO 4
|
|
|
7711c0 |
-
|
|
|
7711c0 |
#define DEFAULT_CLUSTER_SIZE 65536
|
|
|
7711c0 |
|
|
|
7711c0 |
|
|
|
7711c0 |
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
|
|
|
7711c0 |
index e28e1ea..96724a6 100644
|
|
|
7711c0 |
--- a/tests/qemu-iotests/137.out
|
|
|
7711c0 |
+++ b/tests/qemu-iotests/137.out
|
|
|
7711c0 |
@@ -22,7 +22,7 @@ refcount-cache-size may not exceed cache-size
|
|
|
7711c0 |
L2 cache size too big
|
|
|
7711c0 |
L2 cache entry size must be a power of two between 512 and the cluster size (65536)
|
|
|
7711c0 |
L2 cache entry size must be a power of two between 512 and the cluster size (65536)
|
|
|
7711c0 |
-L2 cache size too big
|
|
|
7711c0 |
+Refcount cache size too big
|
|
|
7711c0 |
Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-check.template' ('all')
|
|
|
7711c0 |
Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
|
|
|
7711c0 |
Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
|
|
|
7711c0 |
--
|
|
|
7711c0 |
1.8.3.1
|
|
|
7711c0 |
|