From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, vsementsov@virtuozzo.com,
qemu-devel@nongnu.org, mreitz@redhat.com, den@openvz.org,
jsnow@redhat.com
Subject: [PATCH v3 6/6] block/block-copy: increase buffered copy request
Date: Tue, 22 Oct 2019 14:18:05 +0300 [thread overview]
Message-ID: <20191022111805.3432-7-vsementsov@virtuozzo.com> (raw)
In-Reply-To: <20191022111805.3432-1-vsementsov@virtuozzo.com>
No reason to limit buffered copy to one cluster. Let's allow up to 1
MiB.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
include/block/block-copy.h | 2 +-
block/block-copy.c | 48 +++++++++++++++++++++++++-------------
2 files changed, 33 insertions(+), 17 deletions(-)
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
index edcdf0072d..0a161724d7 100644
--- a/include/block/block-copy.h
+++ b/include/block/block-copy.h
@@ -38,7 +38,7 @@ typedef struct BlockCopyState {
BdrvDirtyBitmap *copy_bitmap;
int64_t cluster_size;
bool use_copy_range;
- int64_t copy_range_size;
+ int64_t copy_size;
uint64_t len;
QLIST_HEAD(, BlockCopyInFlightReq) inflight_reqs;
diff --git a/block/block-copy.c b/block/block-copy.c
index 7f0ebb58f8..c39cc9cffe 100644
--- a/block/block-copy.c
+++ b/block/block-copy.c
@@ -21,6 +21,7 @@
#include "qemu/units.h"
#define BLOCK_COPY_MAX_COPY_RANGE (16 * MiB)
+#define BLOCK_COPY_MAX_BUFFER (1 * MiB)
#define BLOCK_COPY_MAX_MEM (128 * MiB)
static void coroutine_fn block_copy_wait_inflight_reqs(BlockCopyState *s,
@@ -75,10 +76,8 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
{
BlockCopyState *s;
BdrvDirtyBitmap *copy_bitmap;
-
- /* Ignore BLOCK_COPY_MAX_COPY_RANGE if requested cluster_size is larger */
uint32_t max_transfer =
- MIN_NON_ZERO(MAX(cluster_size, BLOCK_COPY_MAX_COPY_RANGE),
+ MIN_NON_ZERO(INT_MAX,
MIN_NON_ZERO(source->bs->bl.max_transfer,
target->bs->bl.max_transfer));
@@ -100,17 +99,28 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
.mem = shres_create(BLOCK_COPY_MAX_MEM),
};
- s->copy_range_size = QEMU_ALIGN_DOWN(max_transfer, cluster_size),
- /*
- * Set use_copy_range, consider the following:
- * 1. Compression is not supported for copy_range.
- * 2. copy_range does not respect max_transfer (it's a TODO), so we factor
- * that in here. If max_transfer is smaller than the job->cluster_size,
- * we do not use copy_range (in that case it's zero after aligning down
- * above).
- */
- s->use_copy_range =
- !(write_flags & BDRV_REQ_WRITE_COMPRESSED) && s->copy_range_size > 0;
+ if (max_transfer < cluster_size) {
+ /*
+ * copy_range does not respect max_transfer. We don't want to bother
+ * with requests smaller than block-copy cluster size, so fallback to
+ * buffered copying (read and write respect max_transfer on their
+ * behalf).
+ */
+ s->use_copy_range = false;
+ s->copy_size = cluster_size;
+ } else if (write_flags & BDRV_REQ_WRITE_COMPRESSED) {
+ /* Compression is not supported for copy_range */
+ s->use_copy_range = false;
+ s->copy_size = MAX(cluster_size, BLOCK_COPY_MAX_BUFFER);
+ } else {
+ /*
+ * copy_range does not respect max_transfer (it's a TODO), so we factor
+ * that in here.
+ */
+ s->use_copy_range = true;
+ s->copy_size = MIN(MAX(cluster_size, BLOCK_COPY_MAX_COPY_RANGE),
+ QEMU_ALIGN_DOWN(max_transfer, cluster_size));
+ }
QLIST_INIT(&s->inflight_reqs);
@@ -156,12 +166,19 @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
if (ret < 0) {
trace_block_copy_copy_range_fail(s, start, ret);
s->use_copy_range = false;
+ s->copy_size = MAX(s->cluster_size, BLOCK_COPY_MAX_BUFFER);
/* Fallback to read+write with allocated buffer */
} else {
goto out;
}
}
+ /*
+ * In case of failed copy_range request above, we may proceed with buffered
+ * request larger than BLOCK_COPY_MAX_BUFFER. Still, further requests will
+ * be properly limited, so don't care too much.
+ */
+
bounce_buffer = qemu_blockalign(s->source->bs, nbytes);
ret = bdrv_co_pread(s->source, start, nbytes, bounce_buffer, 0);
@@ -290,8 +307,7 @@ int coroutine_fn block_copy(BlockCopyState *s,
continue; /* already copied */
}
- chunk_end = MIN(end, start + (s->use_copy_range ?
- s->copy_range_size : s->cluster_size));
+ chunk_end = MIN(end, start + s->copy_size);
next_zero = bdrv_dirty_bitmap_next_zero(s->copy_bitmap, start,
chunk_end - start);
--
2.21.0
next prev parent reply other threads:[~2019-10-22 11:22 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-22 11:17 [PATCH v3 0/6] block-copy: memory limit Vladimir Sementsov-Ogievskiy
2019-10-22 11:18 ` [PATCH v3 1/6] block/block-copy: allocate buffer in block_copy_with_bounce_buffer Vladimir Sementsov-Ogievskiy
2019-10-22 11:18 ` [PATCH v3 2/6] block/block-copy: limit copy_range_size to 16 MiB Vladimir Sementsov-Ogievskiy
2019-10-22 11:18 ` [PATCH v3 3/6] block/block-copy: refactor copying Vladimir Sementsov-Ogievskiy
2019-10-22 11:18 ` [PATCH v3 4/6] util: introduce SharedResource Vladimir Sementsov-Ogievskiy
2019-10-22 11:18 ` [PATCH v3 5/6] block/block-copy: add memory limit Vladimir Sementsov-Ogievskiy
2019-10-22 11:18 ` Vladimir Sementsov-Ogievskiy [this message]
2019-10-25 12:31 ` [PATCH v3 0/6] block-copy: " Max Reitz
2019-10-25 12:32 ` Vladimir Sementsov-Ogievskiy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191022111805.3432-7-vsementsov@virtuozzo.com \
--to=vsementsov@virtuozzo.com \
--cc=den@openvz.org \
--cc=jsnow@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).