From: Anthony Liguori <aliguori@us.ibm.com>
To: Ryan Harper <ryanh@us.ibm.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>,
qemu-devel@nongnu.org, kvm@vger.kernel.org
Subject: [Qemu-devel] Re: [PATCH 2/3] Move aio implementation out of raw block driver
Date: Mon, 22 Sep 2008 21:45:29 -0500 [thread overview]
Message-ID: <48D85849.2080302@us.ibm.com> (raw)
In-Reply-To: <1222125454-21744-3-git-send-email-ryanh@us.ibm.com>
Ryan Harper wrote:
> This patch moves the existing posix aio implementation out of block-raw-posix.c
> into aio-posix.c. Added in a per-block device aio driver abstraction.
> Block-raw-posix invokes the aio driver methods, .submit, .flush, and .cancel as
> needed. aio-posix.c contains the posix aio implementation.
>
> The changes pave the way for other aio implementations, namely linux aio. Each
> block device will init the proper aio driver depending on how the device is
> opened.
>
> Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
>
> diff --git a/Makefile b/Makefile
> index de6393e..18477ba 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -60,7 +60,7 @@ BLOCK_OBJS += block-raw-posix.o
> endif
>
> ifdef CONFIG_AIO
> -BLOCK_OBJS += compatfd.o
> +BLOCK_OBJS += compatfd.o aio-posix.o
> endif
>
> ######################################################################
> diff --git a/Makefile.target b/Makefile.target
> index 4a490f4..4c6b3d5 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -482,7 +482,7 @@ OBJS+=block-raw-posix.o
> endif
>
> ifdef CONFIG_AIO
> -OBJS+=compatfd.o
> +OBJS+=compatfd.o aio-posix.o
> endif
>
> LIBS+=-lz
> diff --git a/block-aio.h b/block-aio.h
> new file mode 100644
> index 0000000..b8597d0
> --- /dev/null
> +++ b/block-aio.h
> @@ -0,0 +1,78 @@
> +/*
> + * QEMU Block AIO API
> + *
> + * Copyright IBM, Corp. 2008
> + *
> + * Authors:
> + * Anthony Liguori <aliguori@us.ibm.com>
> + * Ryan Harper <ryanh@us.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2. See
> + * the COPYING file in the top-level directory.
> + *
> + */
> +
> +#ifndef QEMU_BLOCK_AIO_H
> +#define QEMU_BLOCK_AIO_H
> +
> +#include "qemu-common.h"
> +#include "block_int.h"
> +#include "block.h"
> +#include "qemu-aio.h"
> +#ifdef CONFIG_AIO
> +#include <aio.h>
> +#endif
> +
> +//#define DEBUG_BLOCK_AIO
> +#if defined(DEBUG_BLOCK_AIO)
> +#define BLPRINTF(formatCstr, args...) do { fprintf(stderr, formatCstr, ##args); fflush(stderr); } while (0)
>
This is GCC syntax. You should use C99 syntax. That would be:
#define BLPRINTF(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); }
while (0)
stderr is defined to not be buffered so an explicit fflush is
unnecessary. formatCstr is also a goofy name :-)
> +#else
> +#define BLPRINTF(formatCstr, args...)
>
should be defined to do { } while (0) to maintain statement semantics.
> +#endif
> +
> +typedef struct RawAIOCB {
> + BlockDriverAIOCB common;
> + struct aiocb posix_aiocb;
> + struct RawAIOCB *next;
> + int ret;
> +} RawAIOCB;
>
The whole small-object allocator for AIOCBs seems a bit of a premature
optimization to me. It makes this whole thing terribly awkward.
Marcelo had a patch at one point to switch the small object allocate to
just malloc/free. Marcelo: any reason you didn't follow up with that patch?
> +typedef struct AIODriver
> +{
> + const char *name;
> + RawAIOCB *(*submit)(BlockDriverState *bs, int fd,
> + int64_t sector_num, uint8_t *buf,
> + int sectors, int write,
> + BlockDriverCompletionFunc *cb,
> + void *opaque);
> + void (*cancel)(BlockDriverAIOCB *aiocb);
> + int (*flush)(void *opaque);
> +} AIODriver;
>
I think the AIODriver interface should just take an fd, a completion
function, and an opaque pointer. It should have to have knowledge of
BDRVRawState or BlockDriverState.
> @@ -619,13 +436,14 @@ static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
> }
> #endif
>
> - acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
> - if (!acb)
> + if (fd_open(bs) < 0)
> return NULL;
> - if (aio_read(&acb->aiocb) < 0) {
> - qemu_aio_release(acb);
> +
> + /* submit read */
> + acb = s->aio_dvr->submit(bs, s->fd, sector_num, buf, nb_sectors, 0, cb,
> + opaque);
> + if (!acb)
> return NULL;
> - }
> return &acb->common;
> }
>
So what happens if !defined(CONFIG_AIO)? By my reading of the code,
aio_drv will be NULL and this will SEGV.
> @@ -634,13 +452,13 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
> BlockDriverCompletionFunc *cb, void *opaque)
> {
> RawAIOCB *acb;
> + BDRVRawState *s = bs->opaque;
>
> /*
> * If O_DIRECT is used and the buffer is not aligned fall back
> * to synchronous IO.
> */
> #if defined(O_DIRECT)
> - BDRVRawState *s = bs->opaque;
>
> if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) {
> QEMUBH *bh;
> @@ -652,48 +470,19 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
> }
> #endif
>
> - acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
> + /* submit write */
> + acb = s->aio_dvr->submit(bs, s->fd, sector_num, buf, nb_sectors, 1, cb,
> + opaque);
> if (!acb)
> return NULL;
> - if (aio_write(&acb->aiocb) < 0) {
> - qemu_aio_release(acb);
> - return NULL;
> - }
> return &acb->common;
> }
>
> static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
> {
> - int ret;
> - RawAIOCB *acb = (RawAIOCB *)blockacb;
> - RawAIOCB **pacb;
> -
> - ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
> - if (ret == AIO_NOTCANCELED) {
> - /* fail safe: if the aio could not be canceled, we wait for
> - it */
> - while (aio_error(&acb->aiocb) == EINPROGRESS);
> - }
> -
> - /* remove the callback from the queue */
> - pacb = &posix_aio_state->first_aio;
> - for(;;) {
> - if (*pacb == NULL) {
> - break;
> - } else if (*pacb == acb) {
> - *pacb = acb->next;
> - qemu_aio_release(acb);
> - break;
> - }
> - pacb = &acb->next;
> - }
> -}
> -
> -#else /* CONFIG_AIO */
> -static int posix_aio_init(void)
> -{
> + BDRVRawState *s = blockacb->bs->opaque;
> + s->aio_dvr->cancel(blockacb);
> }
> -#endif /* CONFIG_AIO */
>
> static void raw_close(BlockDriverState *bs)
> {
> @@ -898,8 +687,6 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
> BDRVRawState *s = bs->opaque;
> int fd, open_flags, ret;
>
> - posix_aio_init();
> -
> #ifdef CONFIG_COCOA
> if (strstart(filename, "/dev/cdrom", NULL)) {
> kern_return_t kernResult;
> @@ -969,6 +756,8 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
> s->fd_media_changed = 1;
> }
> #endif
> + /* init aio driver for this block device */
> + s->aio_dvr = posix_aio_init();
>
Doesn't this need to be conditional on CONFIG_AIO?
Regards,
Anthony Liguori
> return 0;
> }
>
>
next prev parent reply other threads:[~2008-09-23 2:46 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-22 23:17 [Qemu-devel] [PATCH 0/3] Refactor AIO to allow multiple AIO implementations Ryan Harper
2008-09-22 23:17 ` [Qemu-devel] [PATCH 1/3] Only call aio flush handler if set Ryan Harper
2008-09-23 2:38 ` [Qemu-devel] " Anthony Liguori
2008-09-23 14:26 ` Ryan Harper
2008-09-23 14:34 ` Anthony Liguori
2008-09-23 14:41 ` Ryan Harper
2008-09-23 14:50 ` Anthony Liguori
2008-09-22 23:17 ` [Qemu-devel] [PATCH 2/3] Move aio implementation out of raw block driver Ryan Harper
2008-09-23 1:16 ` [Qemu-devel] " Ryan Harper
2008-09-23 2:45 ` Anthony Liguori [this message]
2008-09-23 14:39 ` Ryan Harper
2008-09-23 14:40 ` Anthony Liguori
2008-09-23 14:53 ` Gerd Hoffmann
2008-09-23 16:06 ` Anthony Liguori
2008-09-23 18:04 ` Gerd Hoffmann
2008-09-23 18:28 ` Anthony Liguori
2008-09-24 22:31 ` Marcelo Tosatti
2008-09-22 23:17 ` [Qemu-devel] " Ryan Harper
2008-09-23 1:22 ` [Qemu-devel] [PATCH 3/3] Add linux aio implementation for raw block devices Ryan Harper
2008-09-23 3:32 ` [Qemu-devel] Re: [PATCH 0/3] Refactor AIO to allow multiple AIO implementations Anthony Liguori
2008-09-23 14:43 ` Ryan Harper
2008-09-23 14:47 ` Anthony Liguori
2008-09-23 16:09 ` Anthony Liguori
2008-09-23 10:27 ` [Qemu-devel] " Jamie Lokier
2008-10-02 22:41 ` [Qemu-devel] " john cooper
2008-10-03 13:33 ` Ryan Harper
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=48D85849.2080302@us.ibm.com \
--to=aliguori@us.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=mtosatti@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=ryanh@us.ibm.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 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).