qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [6903] virtio-blk: use generic vectored I/O APIs (Christoph Hellwig)
Date: Sat, 28 Mar 2009 17:46:14 +0000	[thread overview]
Message-ID: <E1Lncbm-0008JT-Um@cvs.savannah.gnu.org> (raw)

Revision: 6903
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6903
Author:   aliguori
Date:     2009-03-28 17:46:14 +0000 (Sat, 28 Mar 2009)
Log Message:
-----------
virtio-blk: use generic vectored I/O APIs (Christoph Hellwig)


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>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Modified Paths:
--------------
    trunk/hw/virtio-blk.c

Modified: trunk/hw/virtio-blk.c
===================================================================
--- trunk/hw/virtio-blk.c	2009-03-28 17:46:10 UTC (rev 6902)
+++ trunk/hw/virtio-blk.c	2009-03-28 17:46:14 UTC (rev 6903)
@@ -35,8 +35,7 @@
     VirtQueueElement elem;
     struct virtio_blk_inhdr *in;
     struct virtio_blk_outhdr *out;
-    size_t size;
-    uint8_t *buffer;
+    QEMUIOVector qiov;
     struct VirtIOBlockReq *next;
 } VirtIOBlockReq;
 
@@ -45,10 +44,9 @@
     VirtIOBlock *s = req->dev;
 
     req->in->status = status;
-    virtqueue_push(s->vq, &req->elem, req->size + sizeof(*req->in));
+    virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
     virtio_notify(&s->vdev, s->vq);
 
-    qemu_free(req->buffer);
     qemu_free(req);
 }
 
@@ -76,24 +74,7 @@
 {
     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,16 @@
     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;
+    bdrv_aio_writev(req->dev->bs, req->out->sector, &req->qiov,
+                    req->qiov.size / 512, virtio_blk_rw_complete, req);
+}
 
-        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_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->qiov,
+                   req->qiov.size / 512, virtio_blk_rw_complete, req);
 }
 
 static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
@@ -163,8 +121,6 @@
     VirtIOBlockReq *req;
 
     while ((req = virtio_blk_get_request(s))) {
-        int i;
-
         if (req->elem.out_num < 1 || req->elem.in_num < 1) {
             fprintf(stderr, "virtio-blk missing headers\n");
             exit(1);
@@ -187,23 +143,13 @@
             virtio_notify(vdev, vq);
             qemu_free(req);
         } else if (req->out->type & VIRTIO_BLK_T_OUT) {
-            if (virtio_blk_handle_write(req) < 0)
-                break;
+            qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
+                                     req->elem.out_num - 1);
+            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);
+            qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0],
+                                     req->elem.in_num - 1);
+            virtio_blk_handle_read(req);
         }
     }
     /*

                 reply	other threads:[~2009-03-28 17:46 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=E1Lncbm-0008JT-Um@cvs.savannah.gnu.org \
    --to=anthony@codemonkey.ws \
    --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).