|
|
ae23c9 |
From 85dd7b43885d64406c5ea9af9daefe89a6c7475f Mon Sep 17 00:00:00 2001
|
|
|
ae23c9 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Date: Thu, 6 Dec 2018 17:12:34 +0000
|
|
|
ae23c9 |
Subject: [PATCH 09/15] qcow2: Assign the L2 cache relatively to the image size
|
|
|
ae23c9 |
|
|
|
ae23c9 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Message-id: <20181206171240.5674-10-kwolf@redhat.com>
|
|
|
ae23c9 |
Patchwork-id: 83289
|
|
|
ae23c9 |
O-Subject: [RHEL-8.0 qemu-kvm PATCH 09/15] qcow2: Assign the L2 cache relatively to the image size
|
|
|
ae23c9 |
Bugzilla: 1656507
|
|
|
ae23c9 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
ae23c9 |
RH-Acked-by: John Snow <jsnow@redhat.com>
|
|
|
ae23c9 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
ae23c9 |
|
|
|
ae23c9 |
From: Leonid Bloch <lbloch@janustech.com>
|
|
|
ae23c9 |
|
|
|
ae23c9 |
Sufficient L2 cache can noticeably improve the performance when using
|
|
|
ae23c9 |
large images with frequent I/O.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
Previously, unless 'cache-size' was specified and was large enough, the
|
|
|
ae23c9 |
L2 cache was set to a certain size without taking the virtual image size
|
|
|
ae23c9 |
into account.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
Now, the L2 cache assignment is aware of the virtual size of the image,
|
|
|
ae23c9 |
and will cover the entire image, unless the cache size needed for that is
|
|
|
ae23c9 |
larger than a certain maximum. This maximum is set to 1 MB by default
|
|
|
ae23c9 |
(enough to cover an 8 GB image with the default cluster size) but can
|
|
|
ae23c9 |
be increased or decreased using the 'l2-cache-size' option. This option
|
|
|
ae23c9 |
was previously documented as the *maximum* L2 cache size, and this patch
|
|
|
ae23c9 |
makes it behave as such, instead of as a constant size. Also, the
|
|
|
ae23c9 |
existing option 'cache-size' can limit the sum of both L2 and refcount
|
|
|
ae23c9 |
caches, as previously.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
|
|
|
ae23c9 |
Reviewed-by: Alberto Garcia <berto@igalia.com>
|
|
|
ae23c9 |
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
(cherry picked from commit b749562d9822d14ef69c9eaa5f85903010b86c30)
|
|
|
ae23c9 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
ae23c9 |
---
|
|
|
ae23c9 |
block/qcow2.c | 21 +++++++++------------
|
|
|
ae23c9 |
block/qcow2.h | 4 +---
|
|
|
ae23c9 |
docs/qcow2-cache.txt | 15 ++++++++++-----
|
|
|
ae23c9 |
qemu-options.hx | 6 +++---
|
|
|
ae23c9 |
tests/qemu-iotests/137 | 8 +++++++-
|
|
|
ae23c9 |
tests/qemu-iotests/137.out | 4 +++-
|
|
|
ae23c9 |
6 files changed, 33 insertions(+), 25 deletions(-)
|
|
|
ae23c9 |
|
|
|
ae23c9 |
diff --git a/block/qcow2.c b/block/qcow2.c
|
|
|
ae23c9 |
index f3b2860..fc6bddd 100644
|
|
|
ae23c9 |
--- a/block/qcow2.c
|
|
|
ae23c9 |
+++ b/block/qcow2.c
|
|
|
ae23c9 |
@@ -773,29 +773,35 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
|
|
|
ae23c9 |
uint64_t *refcount_cache_size, Error **errp)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
BDRVQcow2State *s = bs->opaque;
|
|
|
ae23c9 |
- uint64_t combined_cache_size;
|
|
|
ae23c9 |
+ uint64_t combined_cache_size, l2_cache_max_setting;
|
|
|
ae23c9 |
bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set;
|
|
|
ae23c9 |
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
|
|
|
ae23c9 |
+ uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
|
|
|
ae23c9 |
+ uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
|
|
|
ae23c9 |
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
|
|
|
ae23c9 |
refcount_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_REFCOUNT_CACHE_SIZE);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
combined_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_CACHE_SIZE, 0);
|
|
|
ae23c9 |
- *l2_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE, 0);
|
|
|
ae23c9 |
+ l2_cache_max_setting = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE,
|
|
|
ae23c9 |
+ DEFAULT_L2_CACHE_MAX_SIZE);
|
|
|
ae23c9 |
*refcount_cache_size = qemu_opt_get_size(opts,
|
|
|
ae23c9 |
QCOW2_OPT_REFCOUNT_CACHE_SIZE, 0);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
*l2_cache_entry_size = qemu_opt_get_size(
|
|
|
ae23c9 |
opts, QCOW2_OPT_L2_CACHE_ENTRY_SIZE, s->cluster_size);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+ *l2_cache_size = MIN(max_l2_cache, l2_cache_max_setting);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
if (combined_cache_size_set) {
|
|
|
ae23c9 |
if (l2_cache_size_set && refcount_cache_size_set) {
|
|
|
ae23c9 |
error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE
|
|
|
ae23c9 |
" and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set "
|
|
|
ae23c9 |
"the same time");
|
|
|
ae23c9 |
return;
|
|
|
ae23c9 |
- } else if (*l2_cache_size > combined_cache_size) {
|
|
|
ae23c9 |
+ } else if (l2_cache_size_set &&
|
|
|
ae23c9 |
+ (l2_cache_max_setting > combined_cache_size)) {
|
|
|
ae23c9 |
error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed "
|
|
|
ae23c9 |
QCOW2_OPT_CACHE_SIZE);
|
|
|
ae23c9 |
return;
|
|
|
ae23c9 |
@@ -810,9 +816,6 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
|
|
|
ae23c9 |
} else if (refcount_cache_size_set) {
|
|
|
ae23c9 |
*l2_cache_size = combined_cache_size - *refcount_cache_size;
|
|
|
ae23c9 |
} else {
|
|
|
ae23c9 |
- uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
|
|
|
ae23c9 |
- uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
/* Assign as much memory as possible to the L2 cache, and
|
|
|
ae23c9 |
* use the remainder for the refcount cache */
|
|
|
ae23c9 |
if (combined_cache_size >= max_l2_cache + min_refcount_cache) {
|
|
|
ae23c9 |
@@ -824,12 +827,6 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
|
|
|
ae23c9 |
*l2_cache_size = combined_cache_size - *refcount_cache_size;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
- } else {
|
|
|
ae23c9 |
- if (!l2_cache_size_set) {
|
|
|
ae23c9 |
- *l2_cache_size = MAX(DEFAULT_L2_CACHE_SIZE,
|
|
|
ae23c9 |
- (uint64_t)DEFAULT_L2_CACHE_CLUSTERS
|
|
|
ae23c9 |
- * s->cluster_size);
|
|
|
ae23c9 |
- }
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
/* l2_cache_size and refcount_cache_size are ensured to have at least
|
|
|
ae23c9 |
* their minimum values in qcow2_update_options_prepare() */
|
|
|
ae23c9 |
diff --git a/block/qcow2.h b/block/qcow2.h
|
|
|
ae23c9 |
index f73a48a..d0dd4a2 100644
|
|
|
ae23c9 |
--- a/block/qcow2.h
|
|
|
ae23c9 |
+++ b/block/qcow2.h
|
|
|
ae23c9 |
@@ -74,9 +74,7 @@
|
|
|
ae23c9 |
/* Must be at least 4 to cover all cases of refcount table growth */
|
|
|
ae23c9 |
#define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-/* Whichever is more */
|
|
|
ae23c9 |
-#define DEFAULT_L2_CACHE_CLUSTERS 8 /* clusters */
|
|
|
ae23c9 |
-#define DEFAULT_L2_CACHE_SIZE S_1MiB
|
|
|
ae23c9 |
+#define DEFAULT_L2_CACHE_MAX_SIZE S_1MiB
|
|
|
ae23c9 |
|
|
|
ae23c9 |
#define DEFAULT_CLUSTER_SIZE S_64KiB
|
|
|
ae23c9 |
|
|
|
ae23c9 |
diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt
|
|
|
ae23c9 |
index 7e28b41..750447e 100644
|
|
|
ae23c9 |
--- a/docs/qcow2-cache.txt
|
|
|
ae23c9 |
+++ b/docs/qcow2-cache.txt
|
|
|
ae23c9 |
@@ -125,8 +125,12 @@ There are a few things that need to be taken into account:
|
|
|
ae23c9 |
- Both caches must have a size that is a multiple of the cluster size
|
|
|
ae23c9 |
(or the cache entry size: see "Using smaller cache sizes" below).
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- - The default L2 cache size is 8 clusters or 1MB (whichever is more),
|
|
|
ae23c9 |
- and the minimum is 2 clusters (or 2 cache entries, see below).
|
|
|
ae23c9 |
+ - The maximum L2 cache size is 1 MB by default (enough for full coverage
|
|
|
ae23c9 |
+ of 8 GB images, with the default cluster size). This value can be
|
|
|
ae23c9 |
+ modified using the "l2-cache-size" option. QEMU will not use more memory
|
|
|
ae23c9 |
+ than needed to hold all of the image's L2 tables, regardless of this max.
|
|
|
ae23c9 |
+ value. The minimal L2 cache size is 2 clusters (or 2 cache entries, see
|
|
|
ae23c9 |
+ below).
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- The default (and minimum) refcount cache size is 4 clusters.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
@@ -184,9 +188,10 @@ Some things to take into account:
|
|
|
ae23c9 |
always uses the cluster size as the entry size.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- If the L2 cache is big enough to hold all of the image's L2 tables
|
|
|
ae23c9 |
- (as explained in the "Choosing the right cache sizes" section
|
|
|
ae23c9 |
- earlier in this document) then none of this is necessary and you
|
|
|
ae23c9 |
- can omit the "l2-cache-entry-size" parameter altogether.
|
|
|
ae23c9 |
+ (as explained in the "Choosing the right cache sizes" and "How to
|
|
|
ae23c9 |
+ configure the cache sizes" sections in this document) then none of
|
|
|
ae23c9 |
+ this is necessary and you can omit the "l2-cache-entry-size"
|
|
|
ae23c9 |
+ parameter altogether.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
|
|
|
ae23c9 |
Reducing the memory usage
|
|
|
ae23c9 |
diff --git a/qemu-options.hx b/qemu-options.hx
|
|
|
ae23c9 |
index 5e15d6f..5e3bd74 100644
|
|
|
ae23c9 |
--- a/qemu-options.hx
|
|
|
ae23c9 |
+++ b/qemu-options.hx
|
|
|
ae23c9 |
@@ -756,9 +756,9 @@ The maximum total size of the L2 table and refcount block caches in bytes
|
|
|
ae23c9 |
|
|
|
ae23c9 |
@item l2-cache-size
|
|
|
ae23c9 |
The maximum size of the L2 table cache in bytes
|
|
|
ae23c9 |
-(default: if cache-size is not defined - 1048576 bytes or 8 clusters, whichever
|
|
|
ae23c9 |
-is larger; otherwise, as large as possible or needed within the cache-size,
|
|
|
ae23c9 |
-while permitting the requested or the minimal refcount cache size)
|
|
|
ae23c9 |
+(default: if cache-size is not specified - 1M; otherwise, as large as possible
|
|
|
ae23c9 |
+within the cache-size, while permitting the requested or the minimal refcount
|
|
|
ae23c9 |
+cache size)
|
|
|
ae23c9 |
|
|
|
ae23c9 |
@item refcount-cache-size
|
|
|
ae23c9 |
The maximum size of the refcount block cache in bytes
|
|
|
ae23c9 |
diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137
|
|
|
ae23c9 |
index 8796562..19e8597 100755
|
|
|
ae23c9 |
--- a/tests/qemu-iotests/137
|
|
|
ae23c9 |
+++ b/tests/qemu-iotests/137
|
|
|
ae23c9 |
@@ -109,7 +109,6 @@ $QEMU_IO \
|
|
|
ae23c9 |
-c "reopen -o cache-size=1M,l2-cache-size=64k,refcount-cache-size=64k" \
|
|
|
ae23c9 |
-c "reopen -o cache-size=1M,l2-cache-size=2M" \
|
|
|
ae23c9 |
-c "reopen -o cache-size=1M,refcount-cache-size=2M" \
|
|
|
ae23c9 |
- -c "reopen -o l2-cache-size=256T" \
|
|
|
ae23c9 |
-c "reopen -o l2-cache-entry-size=33k" \
|
|
|
ae23c9 |
-c "reopen -o l2-cache-entry-size=128k" \
|
|
|
ae23c9 |
-c "reopen -o refcount-cache-size=256T" \
|
|
|
ae23c9 |
@@ -119,6 +118,13 @@ $QEMU_IO \
|
|
|
ae23c9 |
-c "reopen -o cache-clean-interval=-1" \
|
|
|
ae23c9 |
"$TEST_IMG" | _filter_qemu_io
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+IMGOPTS="cluster_size=256k" _make_test_img 32P
|
|
|
ae23c9 |
+$QEMU_IO \
|
|
|
ae23c9 |
+ -c "reopen -o l2-cache-entry-size=512,l2-cache-size=1T" \
|
|
|
ae23c9 |
+ "$TEST_IMG" | _filter_qemu_io
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+_make_test_img 64M
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
echo
|
|
|
ae23c9 |
echo === Test transaction semantics ===
|
|
|
ae23c9 |
echo
|
|
|
ae23c9 |
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
|
|
|
ae23c9 |
index 96724a6..afcc000 100644
|
|
|
ae23c9 |
--- a/tests/qemu-iotests/137.out
|
|
|
ae23c9 |
+++ b/tests/qemu-iotests/137.out
|
|
|
ae23c9 |
@@ -19,7 +19,6 @@ Parameter 'lazy-refcounts' expects 'on' or 'off'
|
|
|
ae23c9 |
cache-size, l2-cache-size and refcount-cache-size may not be set the same time
|
|
|
ae23c9 |
l2-cache-size may not exceed cache-size
|
|
|
ae23c9 |
refcount-cache-size may not exceed cache-size
|
|
|
ae23c9 |
-L2 cache size too big
|
|
|
ae23c9 |
L2 cache entry size must be a power of two between 512 and the cluster size (65536)
|
|
|
ae23c9 |
L2 cache entry size must be a power of two between 512 and the cluster size (65536)
|
|
|
ae23c9 |
Refcount cache size too big
|
|
|
ae23c9 |
@@ -27,6 +26,9 @@ Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-c
|
|
|
ae23c9 |
Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
|
|
|
ae23c9 |
Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
|
|
|
ae23c9 |
Cache clean interval too big
|
|
|
ae23c9 |
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=36028797018963968
|
|
|
ae23c9 |
+L2 cache size too big
|
|
|
ae23c9 |
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
|
ae23c9 |
|
|
|
ae23c9 |
=== Test transaction semantics ===
|
|
|
ae23c9 |
|
|
|
ae23c9 |
--
|
|
|
ae23c9 |
1.8.3.1
|
|
|
ae23c9 |
|