Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:GA
qemu.20395
0155-qcow2-Assign-the-L2-cache-relativel.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0155-qcow2-Assign-the-L2-cache-relativel.patch of Package qemu.20395
From: Leonid Bloch <lbloch@janustech.com> Date: Wed, 26 Sep 2018 19:04:43 +0300 Subject: qcow2: Assign the L2 cache relatively to the image size Include-If: %if 0%{?suse_version} == 1315 Sufficient L2 cache can noticeably improve the performance when using large images with frequent I/O. Previously, unless 'cache-size' was specified and was large enough, the L2 cache was set to a certain size without taking the virtual image size into account. Now, the L2 cache assignment is aware of the virtual size of the image, and will cover the entire image, unless the cache size needed for that is larger than a certain maximum. This maximum is set to 1 MB by default (enough to cover an 8 GB image with the default cluster size) but can be increased or decreased using the 'l2-cache-size' option. This option was previously documented as the *maximum* L2 cache size, and this patch makes it behave as such, instead of as a constant size. Also, the existing option 'cache-size' can limit the sum of both L2 and refcount caches, as previously. Signed-off-by: Leonid Bloch <lbloch@janustech.com> Reviewed-by: Alberto Garcia <berto@igalia.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> (cherry picked from commit b749562d9822d14ef69c9eaa5f85903010b86c30) [LM: BSC#1139926] Signed-off-by: Lin Ma <lma@suse.com> --- block/qcow2.c | 21 +++++++++------------ block/qcow2.h | 4 +--- docs/qcow2-cache.txt | 8 ++++++-- tests/qemu-iotests/137 | 8 +++++++- tests/qemu-iotests/137.out | 4 +++- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 5b337b749d2e776edd0cf4c0535e..735d7945d5615426ed92579ed930 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -740,26 +740,32 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, uint64_t *refcount_cache_size, Error **errp) { BDRVQcow2State *s = bs->opaque; - uint64_t combined_cache_size; + uint64_t combined_cache_size, l2_cache_max_setting; bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set; int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size; + uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; + uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE); l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE); refcount_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_REFCOUNT_CACHE_SIZE); combined_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_CACHE_SIZE, 0); - *l2_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE, 0); + l2_cache_max_setting = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE, + DEFAULT_L2_CACHE_MAX_SIZE); *refcount_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_REFCOUNT_CACHE_SIZE, 0); + *l2_cache_size = MIN(max_l2_cache, l2_cache_max_setting); + if (combined_cache_size_set) { if (l2_cache_size_set && refcount_cache_size_set) { error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE " and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set " "the same time"); return; - } else if (*l2_cache_size > combined_cache_size) { + } else if (l2_cache_size_set && + (l2_cache_max_setting > combined_cache_size)) { error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " QCOW2_OPT_CACHE_SIZE); return; @@ -774,9 +780,6 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, } else if (refcount_cache_size_set) { *l2_cache_size = combined_cache_size - *refcount_cache_size; } else { - uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; - uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); - /* Assign as much memory as possible to the L2 cache, and * use the remainder for the refcount cache */ if (combined_cache_size >= max_l2_cache + min_refcount_cache) { @@ -788,12 +791,6 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, *l2_cache_size = combined_cache_size - *refcount_cache_size; } } - } else { - if (!l2_cache_size_set) { - *l2_cache_size = MAX(DEFAULT_L2_CACHE_SIZE, - (uint64_t)DEFAULT_L2_CACHE_CLUSTERS - * s->cluster_size); - } } /* l2_cache_size and refcount_cache_size are ensured to have at least * their minimum values in qcow2_update_options_prepare() */ diff --git a/block/qcow2.h b/block/qcow2.h index 00fd00b4bb8b761d462487d919e0..f49c6ea1be02003651cf9a7a9123 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -74,9 +74,7 @@ /* Must be at least 4 to cover all cases of refcount table growth */ #define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */ -/* Whichever is more */ -#define DEFAULT_L2_CACHE_CLUSTERS 8 /* clusters */ -#define DEFAULT_L2_CACHE_SIZE S_1MiB +#define DEFAULT_L2_CACHE_MAX_SIZE S_1MiB #define DEFAULT_CLUSTER_SIZE S_64KiB diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt index d87593dc2fb1f863c8b08dd2fe61..b3be6c0521a6c14eef33b697a40b 100644 --- a/docs/qcow2-cache.txt +++ b/docs/qcow2-cache.txt @@ -125,8 +125,12 @@ There are a few things that need to be taken into account: - Both caches must have a size that is a multiple of the cluster size. - - The default L2 cache size is 8 clusters or 1MB (whichever is more), - and the minimum is 2 clusters (or 2 cache entries, see below). + - The maximum L2 cache size is 1 MB by default (enough for full coverage + of 8 GB images, with the default cluster size). This value can be + modified using the "l2-cache-size" option. QEMU will not use more memory + than needed to hold all of the image's L2 tables, regardless of this max. + value. The minimal L2 cache size is 2 clusters (or 2 cache entries, see + below). - The default (and minimum) refcount cache size is 4 clusters. diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137 index eb91e517d7d4ac2a15eddb5f3182..33774e24b17f9badf1531febeedc 100755 --- a/tests/qemu-iotests/137 +++ b/tests/qemu-iotests/137 @@ -104,7 +104,6 @@ $QEMU_IO \ -c "reopen -o cache-size=1M,l2-cache-size=64k,refcount-cache-size=64k" \ -c "reopen -o cache-size=1M,l2-cache-size=2M" \ -c "reopen -o cache-size=1M,refcount-cache-size=2M" \ - -c "reopen -o l2-cache-size=256T" \ -c "reopen -o refcount-cache-size=256T" \ -c "reopen -o overlap-check=constant,overlap-check.template=all" \ -c "reopen -o overlap-check=blubb" \ @@ -112,6 +111,13 @@ $QEMU_IO \ -c "reopen -o cache-clean-interval=-1" \ "$TEST_IMG" | _filter_qemu_io +IMGOPTS="cluster_size=256k" _make_test_img 32P +$QEMU_IO \ + -c "reopen -o l2-cache-entry-size=512,l2-cache-size=1T" \ + "$TEST_IMG" | _filter_qemu_io + +_make_test_img 64M + echo echo === Test transaction semantics === echo diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out index c4edfc2888a94e1ce360182efff7..28637731afcf69657388afa3e0fc 100644 --- a/tests/qemu-iotests/137.out +++ b/tests/qemu-iotests/137.out @@ -19,12 +19,14 @@ Parameter 'lazy-refcounts' expects 'on' or 'off' cache-size, l2-cache-size and refcount-cache-size may not be set the same time l2-cache-size may not exceed cache-size refcount-cache-size may not exceed cache-size -L2 cache size too big Refcount cache size too big Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-check.template' ('all') Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all Cache clean interval too big +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=36028797018963968 +L2 cache size too big +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 === Test transaction semantics ===
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor