All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrea Arcangeli <aarcange@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [RFC 2/2] bdrv_aio_readv/writev_em
Date: Thu, 27 Nov 2008 13:43:51 +0100	[thread overview]
Message-ID: <20081127124351.GD10348@random.random> (raw)
In-Reply-To: <20081127123538.GC10348@random.random>

Hello,

this is the emulated bdrv_aio_readv/writev pure hack to be able to
test the dma api in previous patch.

About the real thing there are two ways to go:

pthread_create() and do aio with pthreads by calling writev by hand.

Use kernel based linux aio (I think it's much better as it won't
screwup with contiguous I/O, and it handles o_direct random writes and
random reads by keeping the lowlevel I/O pipeline full without threads
but by just queuing _in_order_ [in order only from the point of view
of the I/O scheduler of course] and asynchronously the commands of
every different direct-io aio_readv/writev in the lowlevel storage
queue without needing any scheduler and thread synchronization
involvement).

So who's going to add bdrv_aio_readv/writev instead of the below
aberration that breaks on backend not supporting aio and breaks with
bdrv_aio_cancel too, besides being horribly slow and making direct
path slower than the bounce path?

Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>

Index: block.c
===================================================================
--- block.c	(revision 5799)
+++ block.c	(working copy)
@@ -53,6 +53,20 @@
                         uint8_t *buf, int nb_sectors);
 static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                          const uint8_t *buf, int nb_sectors);
+static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
+					   int64_t sector_num,
+					   struct iovec *iov,
+					   int iovnct,
+					   size_t len,
+					   BlockDriverCompletionFunc *cb,
+					   void *opaque);
+static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
+					    int64_t sector_num,
+					    struct iovec *iov,
+					    int iovnct,
+					    size_t len,
+					    BlockDriverCompletionFunc *cb,
+					    void *opaque);
 
 BlockDriverState *bdrv_first;
 
@@ -135,6 +149,8 @@
         /* add synchronous IO emulation layer */
         bdrv->bdrv_read = bdrv_read_em;
         bdrv->bdrv_write = bdrv_write_em;
+        bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
+        bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
     }
     bdrv->next = first_drv;
     first_drv = bdrv;
@@ -1341,6 +1401,74 @@
     qemu_aio_release(acb);
 }
 
+static void bdrv_aio_iov_bh_cb(void *opaque)
+{
+    BlockDriverAIOCBSync *acb = opaque;
+    acb->common.cb(acb->common.opaque, acb->ret);
+    qemu_bh_delete(acb->bh);
+    qemu_free(acb);
+}
+
+static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
+					   int64_t sector_num,
+					   struct iovec *iov,
+					   int iovcnt,
+					   size_t len,
+					   BlockDriverCompletionFunc *cb,
+					   void *opaque)
+{
+    BlockDriverAIOCBSync *acb;
+    int ret = -1, idx;
+
+    for (idx = 0; idx < iovcnt; idx++) {
+	size_t sectors = iov[idx].iov_len >> SECTOR_BITS;
+	ret = bdrv_read(bs, sector_num, iov[idx].iov_base, sectors);
+	if (ret)
+	    break;
+	sector_num += sectors;
+    }
+    acb = qemu_mallocz(sizeof(BlockDriverAIOCBSync));
+    if (!acb)
+            return NULL;
+    acb->common.bs = bs;
+    acb->common.cb = cb;
+    acb->common.opaque = opaque;
+    acb->bh = qemu_bh_new(bdrv_aio_iov_bh_cb, acb);
+    acb->ret = ret;
+    qemu_bh_schedule(acb->bh);
+    return &acb->common;
+}
+
+static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
+					    int64_t sector_num,
+					    struct iovec *iov,
+					    int iovcnt,
+					    size_t len,
+					    BlockDriverCompletionFunc *cb,
+					    void *opaque)
+{
+    BlockDriverAIOCBSync *acb;
+    int ret = -1, idx;
+
+    for (idx = 0; idx < iovcnt; idx++) {
+	size_t sectors = iov[idx].iov_len >> SECTOR_BITS;
+	ret = bdrv_write(bs, sector_num, iov[idx].iov_base, sectors);
+	if (ret)
+	    break;
+	sector_num += sectors;
+    }
+    acb = qemu_mallocz(sizeof(BlockDriverAIOCBSync));
+    if (!acb)
+            return NULL;
+    acb->common.bs = bs;
+    acb->common.cb = cb;
+    acb->common.opaque = opaque;
+    acb->bh = qemu_bh_new(bdrv_aio_iov_bh_cb, acb);
+    acb->ret = ret;
+    qemu_bh_schedule(acb->bh);
+    return &acb->common;
+}
+
 /**************************************************************/
 /* sync block device emulation */
 

  reply	other threads:[~2008-11-27 12:43 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-27 12:35 [Qemu-devel] [RFC 1/2] pci-dma-api-v1 Andrea Arcangeli
2008-11-27 12:43 ` Andrea Arcangeli [this message]
2008-11-28 11:09   ` [Qemu-devel] [RFC 2/2] bdrv_aio_readv/writev_em Jamie Lokier
2008-11-27 19:14 ` [Qemu-devel] [RFC 1/2] pci-dma-api-v1 Blue Swirl
2008-11-28  1:56   ` Andrea Arcangeli
2008-11-28 17:59     ` Blue Swirl
2008-11-28 18:50       ` Andrea Arcangeli
2008-11-28 19:03         ` Blue Swirl
2008-11-28 19:18           ` Jamie Lokier
2008-11-29 19:49             ` Avi Kivity
2008-11-30 17:20             ` Andrea Arcangeli
2008-11-30 22:31             ` Anthony Liguori
2008-11-30 18:04           ` Andrea Arcangeli
2008-11-30 17:41         ` [Qemu-devel] [RFC 1/1] pci-dma-api-v2 Andrea Arcangeli
2008-11-30 18:36           ` [Qemu-devel] " Blue Swirl
2008-11-30 19:04             ` Andrea Arcangeli
2008-11-30 19:11               ` Blue Swirl
2008-11-30 19:20                 ` Andrea Arcangeli
2008-11-30 21:36                   ` Blue Swirl
2008-11-30 22:54                     ` Anthony Liguori
2008-11-30 22:50           ` [Qemu-devel] " Anthony Liguori
2008-12-01  9:41             ` Avi Kivity
2008-12-01 16:37               ` Anthony Liguori
2008-12-02  9:45                 ` Avi Kivity
2008-11-30 22:38         ` [Qemu-devel] [RFC 1/2] pci-dma-api-v1 Anthony Liguori
2008-11-30 22:51           ` Jamie Lokier
2008-11-30 22:34       ` Anthony Liguori
2008-11-29 19:48   ` Avi Kivity
2008-11-30 17:29     ` Andrea Arcangeli
2008-11-30 20:27       ` Avi Kivity
2008-11-30 22:33         ` Andrea Arcangeli
2008-11-30 22:33   ` Anthony Liguori

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=20081127124351.GD10348@random.random \
    --to=aarcange@redhat.com \
    --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 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.