Blame SOURCES/kvm-qcow2-Assign-the-L2-cache-relatively-to-the-image-si.patch

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