提交 b749562d 编写于 作者: L Leonid Bloch 提交者: Kevin Wolf

qcow2: Assign the L2 cache relatively to the image size

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: NLeonid Bloch <lbloch@janustech.com>
Reviewed-by: NAlberto Garcia <berto@igalia.com>
Reviewed-by: NKevin Wolf <kwolf@redhat.com>
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
上级 657ada52
...@@ -777,29 +777,35 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, ...@@ -777,29 +777,35 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
uint64_t *refcount_cache_size, Error **errp) uint64_t *refcount_cache_size, Error **errp)
{ {
BDRVQcow2State *s = bs->opaque; 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; bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set;
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size; 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); 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); 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); 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); 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, *refcount_cache_size = qemu_opt_get_size(opts,
QCOW2_OPT_REFCOUNT_CACHE_SIZE, 0); QCOW2_OPT_REFCOUNT_CACHE_SIZE, 0);
*l2_cache_entry_size = qemu_opt_get_size( *l2_cache_entry_size = qemu_opt_get_size(
opts, QCOW2_OPT_L2_CACHE_ENTRY_SIZE, s->cluster_size); opts, QCOW2_OPT_L2_CACHE_ENTRY_SIZE, s->cluster_size);
*l2_cache_size = MIN(max_l2_cache, l2_cache_max_setting);
if (combined_cache_size_set) { if (combined_cache_size_set) {
if (l2_cache_size_set && refcount_cache_size_set) { if (l2_cache_size_set && refcount_cache_size_set) {
error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE
" and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set " " and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set "
"at the same time"); "at the same time");
return; 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 " error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed "
QCOW2_OPT_CACHE_SIZE); QCOW2_OPT_CACHE_SIZE);
return; return;
...@@ -814,9 +820,6 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, ...@@ -814,9 +820,6 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
} else if (refcount_cache_size_set) { } else if (refcount_cache_size_set) {
*l2_cache_size = combined_cache_size - *refcount_cache_size; *l2_cache_size = combined_cache_size - *refcount_cache_size;
} else { } 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 /* Assign as much memory as possible to the L2 cache, and
* use the remainder for the refcount cache */ * use the remainder for the refcount cache */
if (combined_cache_size >= max_l2_cache + min_refcount_cache) { if (combined_cache_size >= max_l2_cache + min_refcount_cache) {
...@@ -828,12 +831,6 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, ...@@ -828,12 +831,6 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
*l2_cache_size = combined_cache_size - *refcount_cache_size; *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 /* l2_cache_size and refcount_cache_size are ensured to have at least
* their minimum values in qcow2_update_options_prepare() */ * their minimum values in qcow2_update_options_prepare() */
......
...@@ -74,9 +74,7 @@ ...@@ -74,9 +74,7 @@
/* Must be at least 4 to cover all cases of refcount table growth */ /* Must be at least 4 to cover all cases of refcount table growth */
#define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */ #define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */
/* Whichever is more */ #define DEFAULT_L2_CACHE_MAX_SIZE S_1MiB
#define DEFAULT_L2_CACHE_CLUSTERS 8 /* clusters */
#define DEFAULT_L2_CACHE_SIZE S_1MiB
#define DEFAULT_CLUSTER_SIZE S_64KiB #define DEFAULT_CLUSTER_SIZE S_64KiB
......
...@@ -125,8 +125,12 @@ There are a few things that need to be taken into account: ...@@ -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 - Both caches must have a size that is a multiple of the cluster size
(or the cache entry size: see "Using smaller cache sizes" below). (or the cache entry size: see "Using smaller cache sizes" below).
- The default L2 cache size is 8 clusters or 1MB (whichever is more), - The maximum L2 cache size is 1 MB by default (enough for full coverage
and the minimum is 2 clusters (or 2 cache entries, see below). 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. - The default (and minimum) refcount cache size is 4 clusters.
...@@ -184,9 +188,10 @@ Some things to take into account: ...@@ -184,9 +188,10 @@ Some things to take into account:
always uses the cluster size as the entry size. always uses the cluster size as the entry size.
- If the L2 cache is big enough to hold all of the image's L2 tables - If the L2 cache is big enough to hold all of the image's L2 tables
(as explained in the "Choosing the right cache sizes" section (as explained in the "Choosing the right cache sizes" and "How to
earlier in this document) then none of this is necessary and you configure the cache sizes" sections in this document) then none of
can omit the "l2-cache-entry-size" parameter altogether. this is necessary and you can omit the "l2-cache-entry-size"
parameter altogether.
Reducing the memory usage Reducing the memory usage
......
...@@ -736,9 +736,9 @@ The maximum total size of the L2 table and refcount block caches in bytes ...@@ -736,9 +736,9 @@ The maximum total size of the L2 table and refcount block caches in bytes
@item l2-cache-size @item l2-cache-size
The maximum size of the L2 table cache in bytes The maximum size of the L2 table cache in bytes
(default: if cache-size is not defined - 1048576 bytes or 8 clusters, whichever (default: if cache-size is not specified - 1M; otherwise, as large as possible
is larger; otherwise, as large as possible or needed within the cache-size, within the cache-size, while permitting the requested or the minimal refcount
while permitting the requested or the minimal refcount cache size) cache size)
@item refcount-cache-size @item refcount-cache-size
The maximum size of the refcount block cache in bytes The maximum size of the refcount block cache in bytes
......
...@@ -109,7 +109,6 @@ $QEMU_IO \ ...@@ -109,7 +109,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=64k,refcount-cache-size=64k" \
-c "reopen -o cache-size=1M,l2-cache-size=2M" \ -c "reopen -o cache-size=1M,l2-cache-size=2M" \
-c "reopen -o cache-size=1M,refcount-cache-size=2M" \ -c "reopen -o cache-size=1M,refcount-cache-size=2M" \
-c "reopen -o l2-cache-size=256T" \
-c "reopen -o l2-cache-entry-size=33k" \ -c "reopen -o l2-cache-entry-size=33k" \
-c "reopen -o l2-cache-entry-size=128k" \ -c "reopen -o l2-cache-entry-size=128k" \
-c "reopen -o refcount-cache-size=256T" \ -c "reopen -o refcount-cache-size=256T" \
...@@ -119,6 +118,13 @@ $QEMU_IO \ ...@@ -119,6 +118,13 @@ $QEMU_IO \
-c "reopen -o cache-clean-interval=-1" \ -c "reopen -o cache-clean-interval=-1" \
"$TEST_IMG" | _filter_qemu_io "$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
echo === Test transaction semantics === echo === Test transaction semantics ===
echo echo
......
...@@ -19,7 +19,6 @@ Parameter 'lazy-refcounts' expects 'on' or 'off' ...@@ -19,7 +19,6 @@ Parameter 'lazy-refcounts' expects 'on' or 'off'
cache-size, l2-cache-size and refcount-cache-size may not be set at the same time cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
l2-cache-size may not exceed cache-size l2-cache-size may not exceed cache-size
refcount-cache-size may not exceed cache-size refcount-cache-size may not exceed cache-size
L2 cache size too big
L2 cache entry size must be a power of two between 512 and the cluster size (65536) L2 cache entry size must be a power of two between 512 and the cluster size (65536)
L2 cache entry size must be a power of two between 512 and the cluster size (65536) L2 cache entry size must be a power of two between 512 and the cluster size (65536)
Refcount cache size too big Refcount cache size too big
...@@ -27,6 +26,9 @@ Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-c ...@@ -27,6 +26,9 @@ Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-c
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
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 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 === === Test transaction semantics ===
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册