qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 3/6] virtio-blk: use generic vectored I/O APIs
Date: Sat, 14 Mar 2009 20:28:49 +0100	[thread overview]
Message-ID: <20090314192849.GC3717@lst.de> (raw)
In-Reply-To: <20090314192701.GA3497@lst.de>


Use the generic bdrv_aio_readv/bdrv_aio_writev APIs instead of linearizing
buffers directly.  This enables using the future native preadv/pwritev
support.


Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: qemu/hw/virtio-blk.c
===================================================================
--- qemu.orig/hw/virtio-blk.c	2009-03-10 16:14:37.000000000 +0100
+++ qemu/hw/virtio-blk.c	2009-03-11 03:03:43.000000000 +0100
@@ -36,7 +36,6 @@ typedef struct VirtIOBlockReq
     struct virtio_blk_inhdr *in;
     struct virtio_blk_outhdr *out;
     size_t size;
-    uint8_t *buffer;
     struct VirtIOBlockReq *next;
 } VirtIOBlockReq;
 
@@ -48,7 +47,6 @@ static void virtio_blk_req_complete(Virt
     virtqueue_push(s->vq, &req->elem, req->size + sizeof(*req->in));
     virtio_notify(&s->vdev, s->vq);
 
-    qemu_free(req->buffer);
     qemu_free(req);
 }
 
@@ -76,24 +74,7 @@ static void virtio_blk_rw_complete(void 
 {
     VirtIOBlockReq *req = opaque;
 
-    /* Copy read data to the guest */
-    if (!ret && !(req->out->type & VIRTIO_BLK_T_OUT)) {
-        size_t offset = 0;
-        int i;
-
-        for (i = 0; i < req->elem.in_num - 1; i++) {
-            size_t len;
-
-            /* Be pretty defensive wrt malicious guests */
-            len = MIN(req->elem.in_sg[i].iov_len,
-                      req->size - offset);
-
-            memcpy(req->elem.in_sg[i].iov_base,
-                   req->buffer + offset,
-                   len);
-            offset += len;
-        }
-    } else if (ret && (req->out->type & VIRTIO_BLK_T_OUT)) {
+    if (ret && (req->out->type & VIRTIO_BLK_T_OUT)) {
         if (virtio_blk_handle_write_error(req, -ret))
             return;
     }
@@ -122,39 +103,18 @@ static VirtIOBlockReq *virtio_blk_get_re
     return req;
 }
 
-static int virtio_blk_handle_write(VirtIOBlockReq *req)
+static void virtio_blk_handle_write(VirtIOBlockReq *req)
 {
-    if (!req->buffer) {
-        size_t offset = 0;
-        int i;
-
-        for (i = 1; i < req->elem.out_num; i++)
-            req->size += req->elem.out_sg[i].iov_len;
-
-        req->buffer = qemu_memalign(512, req->size);
-        if (req->buffer == NULL) {
-            qemu_free(req);
-            return -1;
-        }
-
-        /* We copy the data from the SG list to avoid splitting up the request.
-           This helps performance a lot until we can pass full sg lists as AIO
-           operations */
-        for (i = 1; i < req->elem.out_num; i++) {
-            size_t len;
-
-            len = MIN(req->elem.out_sg[i].iov_len,
-                    req->size - offset);
-            memcpy(req->buffer + offset,
-                    req->elem.out_sg[i].iov_base,
-                    len);
-            offset += len;
-        }
-    }
+    bdrv_aio_writev(req->dev->bs, req->out->sector, &req->elem.out_sg[0],
+                    req->elem.out_num, req->size / 512,
+                    virtio_blk_rw_complete, req);
+}
 
-    bdrv_aio_write(req->dev->bs, req->out->sector, req->buffer, req->size / 512,
-            virtio_blk_rw_complete, req);
-    return 0;
+static void virtio_blk_handle_read(VirtIOBlockReq *req)
+{
+    bdrv_aio_readv(req->dev->bs, req->out->sector, &req->elem.in_sg[0],
+                   req->elem.in_num, req->size / 512,
+                   virtio_blk_rw_complete, req);
 }
 
 static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
@@ -187,23 +147,13 @@ static void virtio_blk_handle_output(Vir
             virtio_notify(vdev, vq);
             qemu_free(req);
         } else if (req->out->type & VIRTIO_BLK_T_OUT) {
-            if (virtio_blk_handle_write(req) < 0)
-                break;
+            for (i = 1; i < req->elem.out_num; i++)
+                req->size += req->elem.out_sg[i].iov_len;
+            virtio_blk_handle_write(req);
         } else {
             for (i = 0; i < req->elem.in_num - 1; i++)
                 req->size += req->elem.in_sg[i].iov_len;
-
-            req->buffer = qemu_memalign(512, req->size);
-            if (req->buffer == NULL) {
-                qemu_free(req);
-                break;
-            }
-
-            bdrv_aio_read(s->bs, req->out->sector,
-                          req->buffer,
-                          req->size / 512,
-                          virtio_blk_rw_complete,
-                          req);
+            virtio_blk_handle_read(req);
         }
     }
     /*

  parent reply	other threads:[~2009-03-14 19:28 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-14 19:27 [Qemu-devel] [PATCH 0/6] add real vectored block I/O support Christoph Hellwig
2009-03-14 19:27 ` [Qemu-devel] [PATCH 1/6] more BlockDriver C99 initializers Christoph Hellwig
2009-03-28 18:35   ` Christoph Hellwig
2009-03-14 19:28 ` [Qemu-devel] [PATCH 2/6] change vectored block I/O API to plain iovecs Christoph Hellwig
2009-03-15 12:42   ` Avi Kivity
2009-03-15 13:20     ` Anthony Liguori
2009-03-15 13:36       ` Avi Kivity
2009-03-15 14:48     ` Christoph Hellwig
2009-03-15 15:07       ` Avi Kivity
2009-03-15 16:35         ` Christoph Hellwig
2009-03-14 19:28 ` Christoph Hellwig [this message]
2009-03-14 19:30 ` [Qemu-devel] [PATCH 4/6] remove bdrv_aio_read/bdrv_aio_write Christoph Hellwig
2009-03-14 19:30 ` [Qemu-devel] [PATCH 5/6] push down vector linearization to posix-aio-compat.c Christoph Hellwig
2009-03-14 19:31 ` [Qemu-devel] [PATCH 6/6] experimental native preadv/pwritev support for Linux Christoph Hellwig
2009-03-15 14:36   ` Blue Swirl
2009-03-15 14:44     ` Christoph Hellwig
2009-03-15 15:03       ` Blue Swirl
2009-03-15 15:16         ` Christoph Hellwig
2009-03-16 11:38   ` Gerd Hoffmann
2009-03-16 11:53     ` Christoph Hellwig

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=20090314192849.GC3717@lst.de \
    --to=hch@lst.de \
    --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).