[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 09/29] qcow2: Add runtime options for cache sizes
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PULL 09/29] qcow2: Add runtime options for cache sizes |
Date: |
Fri, 22 Aug 2014 16:51:33 +0200 |
From: Max Reitz <address@hidden>
Add options for specifying the size of the metadata caches. This can
either be done directly for each cache (if only one is given, the other
will be derived according to a default ratio) or combined for both.
Signed-off-by: Max Reitz <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block/qcow2.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
block/qcow2.h | 3 ++
2 files changed, 103 insertions(+), 11 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index 0f1be2e..f9e045f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -442,6 +442,22 @@ static QemuOptsList qcow2_runtime_opts = {
.type = QEMU_OPT_BOOL,
.help = "Check for unintended writes into an inactive L2 table",
},
+ {
+ .name = QCOW2_OPT_CACHE_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Maximum combined metadata (L2 tables and refcount blocks)
"
+ "cache size",
+ },
+ {
+ .name = QCOW2_OPT_L2_CACHE_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Maximum L2 table cache size",
+ },
+ {
+ .name = QCOW2_OPT_REFCOUNT_CACHE_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Maximum refcount block cache size",
+ },
{ /* end of list */ }
},
};
@@ -457,6 +473,61 @@ static const char
*overlap_bool_option_names[QCOW2_OL_MAX_BITNR] = {
[QCOW2_OL_INACTIVE_L2_BITNR] = QCOW2_OPT_OVERLAP_INACTIVE_L2,
};
+static void read_cache_sizes(QemuOpts *opts, uint64_t *l2_cache_size,
+ uint64_t *refcount_cache_size, Error **errp)
+{
+ uint64_t combined_cache_size;
+ bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set;
+
+ 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);
+ *refcount_cache_size = qemu_opt_get_size(opts,
+ QCOW2_OPT_REFCOUNT_CACHE_SIZE, 0);
+
+ 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) {
+ error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed "
+ QCOW2_OPT_CACHE_SIZE);
+ return;
+ } else if (*refcount_cache_size > combined_cache_size) {
+ error_setg(errp, QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not exceed "
+ QCOW2_OPT_CACHE_SIZE);
+ return;
+ }
+
+ if (l2_cache_size_set) {
+ *refcount_cache_size = combined_cache_size - *l2_cache_size;
+ } else if (refcount_cache_size_set) {
+ *l2_cache_size = combined_cache_size - *refcount_cache_size;
+ } else {
+ *refcount_cache_size = combined_cache_size
+ / (DEFAULT_L2_REFCOUNT_SIZE_RATIO + 1);
+ *l2_cache_size = combined_cache_size - *refcount_cache_size;
+ }
+ } else {
+ if (!l2_cache_size_set && !refcount_cache_size_set) {
+ *l2_cache_size = DEFAULT_L2_CACHE_BYTE_SIZE;
+ *refcount_cache_size = *l2_cache_size
+ / DEFAULT_L2_REFCOUNT_SIZE_RATIO;
+ } else if (!l2_cache_size_set) {
+ *l2_cache_size = *refcount_cache_size
+ * DEFAULT_L2_REFCOUNT_SIZE_RATIO;
+ } else if (!refcount_cache_size_set) {
+ *refcount_cache_size = *l2_cache_size
+ / DEFAULT_L2_REFCOUNT_SIZE_RATIO;
+ }
+ }
+}
+
static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
@@ -707,17 +778,43 @@ static int qcow2_open(BlockDriverState *bs, QDict
*options, int flags,
}
}
- /* alloc L2 table/refcount block cache */
- l2_cache_size = DEFAULT_L2_CACHE_BYTE_SIZE / s->cluster_size;
+ /* get L2 table/refcount block cache size from command line options */
+ opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort);
+ qemu_opts_absorb_qdict(opts, options, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ read_cache_sizes(opts, &l2_cache_size, &refcount_cache_size, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ l2_cache_size /= s->cluster_size;
if (l2_cache_size < MIN_L2_CACHE_SIZE) {
l2_cache_size = MIN_L2_CACHE_SIZE;
}
+ if (l2_cache_size > INT_MAX) {
+ error_setg(errp, "L2 cache size too big");
+ ret = -EINVAL;
+ goto fail;
+ }
- refcount_cache_size = l2_cache_size / DEFAULT_L2_REFCOUNT_SIZE_RATIO;
+ refcount_cache_size /= s->cluster_size;
if (refcount_cache_size < MIN_REFCOUNT_CACHE_SIZE) {
refcount_cache_size = MIN_REFCOUNT_CACHE_SIZE;
}
+ if (refcount_cache_size > INT_MAX) {
+ error_setg(errp, "Refcount cache size too big");
+ ret = -EINVAL;
+ goto fail;
+ }
+ /* alloc L2 table/refcount block cache */
s->l2_table_cache = qcow2_cache_create(bs, l2_cache_size);
s->refcount_block_cache = qcow2_cache_create(bs, refcount_cache_size);
if (s->l2_table_cache == NULL || s->refcount_block_cache == NULL) {
@@ -809,14 +906,6 @@ static int qcow2_open(BlockDriverState *bs, QDict
*options, int flags,
}
/* Enable lazy_refcounts according to image and command line options */
- opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort);
- qemu_opts_absorb_qdict(opts, options, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- ret = -EINVAL;
- goto fail;
- }
-
s->use_lazy_refcounts = qemu_opt_get_bool(opts, QCOW2_OPT_LAZY_REFCOUNTS,
(s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS));
diff --git a/block/qcow2.h b/block/qcow2.h
index 671783d..6aeb7ea 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -91,6 +91,9 @@
#define QCOW2_OPT_OVERLAP_SNAPSHOT_TABLE "overlap-check.snapshot-table"
#define QCOW2_OPT_OVERLAP_INACTIVE_L1 "overlap-check.inactive-l1"
#define QCOW2_OPT_OVERLAP_INACTIVE_L2 "overlap-check.inactive-l2"
+#define QCOW2_OPT_CACHE_SIZE "cache-size"
+#define QCOW2_OPT_L2_CACHE_SIZE "l2-cache-size"
+#define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
typedef struct QCowHeader {
uint32_t magic;
--
1.8.3.1
- [Qemu-devel] [PULL 00/29] Block patches, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 03/29] qemu-io-cmds: g_renew() can't fail, bury dead error handling, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 02/29] block: Use g_new() & friends to avoid multiplying sizes, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 01/29] block: Use g_new() & friends where that makes obvious sense, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 05/29] runner: Add an argument for test duration, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 04/29] block: Drop some superfluous casts from void *, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 06/29] runner: Kill a program under test by time-out, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 08/29] qcow2: Use g_try_new0() for cache array, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 07/29] qcow2: Constant cache size in bytes, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 10/29] iotests: Add test for qcow2's cache options, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 09/29] qcow2: Add runtime options for cache sizes,
Kevin Wolf <=
- [Qemu-devel] [PULL 11/29] test-coroutine: test cost introduced by coroutine, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 12/29] qemu-iotests: Fix 028 reference output for qed, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 14/29] virtio-blk: allow block_resize with dataplane, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 13/29] block: acquire AioContext in qmp_block_resize(), Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 15/29] virtio-blk: fix reference a pointer which might be freed, Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 17/29] blkdebug: Implement bdrv_refresh_filename(), Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 16/29] block: Add bdrv_refresh_filename(), Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 18/29] blkverify: Implement bdrv_refresh_filename(), Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 19/29] nbd: Implement bdrv_refresh_filename(), Kevin Wolf, 2014/08/22
- [Qemu-devel] [PULL 21/29] iotests: Add test for image filename construction, Kevin Wolf, 2014/08/22