From: Kevin Wolf <kwolf@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel@nongnu.org, stefanha@redhat.com
Subject: Re: [Qemu-devel] [PATCH v2 11/12] mirror: support more than one in-flight AIO operation
Date: Mon, 21 Jan 2013 13:35:43 +0100 [thread overview]
Message-ID: <50FD361F.1050608@redhat.com> (raw)
In-Reply-To: <1358357479-7912-12-git-send-email-pbonzini@redhat.com>
Am 16.01.2013 18:31, schrieb Paolo Bonzini:
> With AIO support in place, we can start copying more than one chunk
> in parallel. This patch introduces the required infrastructure for
> this: the buffer is split into multiple granularity-sized chunks,
> and there is a free list to access them.
>
> Because of copy-on-write, a single operation may already require
> multiple chunks to be available on the free list.
>
> In addition, two different iterations on the HBitmap may want to
> copy the same cluster. We avoid this by keeping a bitmap of in-flight
> I/O operations, and blocking until the previous iteration completes.
> This should be a pretty rare occurrence, though; as long as there is
> no overlap the next iteration can start before the previous one finishes.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
I'm wondering if a whole bitmap is really appropriate when you have at
most 16 parallel requests in flight. Other places in qemu (like
copy-on-read or qcow2 cluster allocation) use lists of in-flight
requests instead.
I'm not requesting a change here, just wondering what the reasons are
and whether this, or the other places, or none of both should be changed
long term.
> ---
> v1->v2: the in_flight_bitmap is now properly set and cleared [Stefan]
>
> block/mirror.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++------
> trace-events | 4 ++-
> 2 files changed, 102 insertions(+), 13 deletions(-)
>
> diff --git a/block/mirror.c b/block/mirror.c
> index 77bb184..686d2b7 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -17,7 +17,15 @@
> #include "qemu/ratelimit.h"
> #include "qemu/bitmap.h"
>
> -#define SLICE_TIME 100000000ULL /* ns */
> +#define SLICE_TIME 100000000ULL /* ns */
> +#define MAX_IN_FLIGHT 16
> +
> +/* The mirroring buffer is a list of granularity-sized chunks.
> + * Free chunks are organized in a list.
> + */
> +typedef struct MirrorBuffer {
> + QSIMPLEQ_ENTRY(MirrorBuffer) next;
> +} MirrorBuffer;
>
> typedef struct MirrorBlockJob {
> BlockJob common;
> @@ -33,7 +41,10 @@ typedef struct MirrorBlockJob {
> unsigned long *cow_bitmap;
> HBitmapIter hbi;
> uint8_t *buf;
> + QSIMPLEQ_HEAD(, MirrorBuffer) buf_free;
> + int buf_free_count;
>
> + unsigned long *in_flight_bitmap;
> int in_flight;
> int ret;
> } MirrorBlockJob;
> @@ -41,7 +52,6 @@ typedef struct MirrorBlockJob {
> typedef struct MirrorOp {
> MirrorBlockJob *s;
> QEMUIOVector qiov;
> - struct iovec iov;
> int64_t sector_num;
> int nb_sectors;
> } MirrorOp;
> @@ -62,8 +72,23 @@ static BlockErrorAction mirror_error_action(MirrorBlockJob *s, bool read,
> static void mirror_iteration_done(MirrorOp *op)
> {
> MirrorBlockJob *s = op->s;
> + struct iovec *iov;
> + int64_t cluster_num;
> + int i, nb_chunks, nb_sectors_chunk;
>
> s->in_flight--;
> + iov = op->qiov.iov;
> + for (i = 0; i < op->qiov.niov; i++) {
> + MirrorBuffer *buf = (MirrorBuffer *) iov[i].iov_base;
> + QSIMPLEQ_INSERT_TAIL(&s->buf_free, buf, next);
> + s->buf_free_count++;
> + }
> +
> + nb_sectors_chunk = s->granularity >> BDRV_SECTOR_BITS;
> + cluster_num = op->sector_num / nb_sectors_chunk;
> + nb_chunks = op->nb_sectors / nb_sectors_chunk;
> + bitmap_clear(s->in_flight_bitmap, cluster_num, nb_chunks);
> +
> trace_mirror_iteration_done(s, op->sector_num, op->nb_sectors);
> g_slice_free(MirrorOp, op);
> qemu_coroutine_enter(s->common.co, NULL);
> @@ -110,8 +135,8 @@ static void mirror_read_complete(void *opaque, int ret)
> static void coroutine_fn mirror_iteration(MirrorBlockJob *s)
> {
> BlockDriverState *source = s->common.bs;
> - int nb_sectors, nb_sectors_chunk;
> - int64_t end, sector_num, cluster_num;
> + int nb_sectors, nb_sectors_chunk, nb_chunks;
> + int64_t end, sector_num, cluster_num, next_sector, hbitmap_next_sector;
> MirrorOp *op;
>
> s->sector_num = hbitmap_iter_next(&s->hbi);
> @@ -122,6 +147,8 @@ static void coroutine_fn mirror_iteration(MirrorBlockJob *s)
> assert(s->sector_num >= 0);
> }
>
> + hbitmap_next_sector = s->sector_num;
Is there even a reason why s->sector_num exists in the first place? If
I'm not mistaken, it's only used locally and could live on the stack as
hbitmap_next_sector from the beginning.
Kevin
next prev parent reply other threads:[~2013-01-21 12:35 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-16 17:31 [Qemu-devel] [PATCH v2 00/12] Drive mirroring performance improvements Paolo Bonzini
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 01/12] host-utils: add ffsl Paolo Bonzini
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 02/12] add hierarchical bitmap data type and test cases Paolo Bonzini
2013-01-16 22:50 ` Eric Blake
2013-01-18 13:21 ` Kevin Wolf
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 03/12] block: implement dirty bitmap using HBitmap Paolo Bonzini
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 04/12] block: make round_to_clusters public Paolo Bonzini
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 05/12] mirror: perform COW if the cluster size is bigger than the granularity Paolo Bonzini
2013-01-18 15:13 ` Kevin Wolf
2013-01-18 16:22 ` Paolo Bonzini
2013-01-18 17:05 ` Kevin Wolf
2013-01-18 17:33 ` Paolo Bonzini
2013-01-21 10:17 ` Kevin Wolf
2013-01-21 11:15 ` Paolo Bonzini
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 06/12] block: return count of dirty sectors, not chunks Paolo Bonzini
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 07/12] block: allow customizing the granularity of the dirty bitmap Paolo Bonzini
2013-01-16 23:39 ` Eric Blake
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 08/12] mirror: allow customizing the granularity Paolo Bonzini
2013-01-16 23:44 ` Eric Blake
2013-01-21 11:00 ` Kevin Wolf
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 09/12] mirror: switch mirror_iteration to AIO Paolo Bonzini
2013-01-21 11:39 ` Kevin Wolf
2013-01-21 12:09 ` Paolo Bonzini
2013-01-21 12:15 ` Kevin Wolf
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 10/12] mirror: add buf-size argument to drive-mirror Paolo Bonzini
2013-01-16 23:46 ` Eric Blake
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 11/12] mirror: support more than one in-flight AIO operation Paolo Bonzini
2013-01-21 12:35 ` Kevin Wolf [this message]
2013-01-21 12:55 ` Paolo Bonzini
2013-01-16 17:31 ` [Qemu-devel] [PATCH v2 12/12] mirror: support arbitrarily-sized iterations Paolo Bonzini
2013-01-16 23:48 ` [Qemu-devel] [PATCH v2 00/12] Drive mirroring performance improvements Eric Blake
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=50FD361F.1050608@redhat.com \
--to=kwolf@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.