public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [patch 0/2] virtio-blk async IO (v3)
@ 2008-06-05  5:01 Marcelo Tosatti
  2008-06-05  5:01 ` [patch 1/2] QEMU/KVM: provide a reset method for virtio Marcelo Tosatti
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Marcelo Tosatti @ 2008-06-05  5:01 UTC (permalink / raw)
  To: Avi Kivity, Anthony Liguori; +Cc: kvm, Gerd v. Egidy

Resending the virtio-blk async patches, now that the reason for Gerd's
hangs are known.

The above results are on host hot-cached data, cold-cache data workloads
are the real winners, where the current code waits until each read
request is finished before submitting the next one.

ide:
Version  1.03       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
localhost.locald 2G 36618  88 107274  31 80361  49 44311  98 292436  94 +++++ +++

virtio-blk:

Version  1.03       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
localhost.locald 2G 39738  89 108389  31 82313  48 43943  98 290500  94 +++++ +++

virtio-blk-async:

Version  1.03       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
localhost.locald 2G 40781  92 102806  34 86887  36 44339  97 347461  78 +++++ +++


-- 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [patch 1/2] QEMU/KVM: provide a reset method for virtio
  2008-06-05  5:01 [patch 0/2] virtio-blk async IO (v3) Marcelo Tosatti
@ 2008-06-05  5:01 ` Marcelo Tosatti
  2008-06-05  5:01 ` [patch 2/2] QEMU/KVM: virtio-blk async IO (v3) Marcelo Tosatti
  2008-06-05  7:50 ` [patch 0/2] " Avi Kivity
  2 siblings, 0 replies; 4+ messages in thread
From: Marcelo Tosatti @ 2008-06-05  5:01 UTC (permalink / raw)
  To: Avi Kivity, Anthony Liguori; +Cc: kvm, Gerd v. Egidy, Marcelo Tosatti

[-- Attachment #1: virtio-reset --]
[-- Type: text/plain, Size: 1030 bytes --]

So drivers can do whatever necessary on reset.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

Index: kvm-userspace.vblk/qemu/hw/virtio.c
===================================================================
--- kvm-userspace.vblk.orig/qemu/hw/virtio.c
+++ kvm-userspace.vblk/qemu/hw/virtio.c
@@ -207,6 +207,9 @@ void virtio_reset(void *opaque)
     VirtIODevice *vdev = opaque;
     int i;
 
+    if (vdev->reset)
+        vdev->reset(vdev);
+
     vdev->features = 0;
     vdev->queue_sel = 0;
     vdev->status = 0;
Index: kvm-userspace.vblk/qemu/hw/virtio.h
===================================================================
--- kvm-userspace.vblk.orig/qemu/hw/virtio.h
+++ kvm-userspace.vblk/qemu/hw/virtio.h
@@ -116,6 +116,7 @@ struct VirtIODevice
     uint32_t (*get_features)(VirtIODevice *vdev);
     void (*set_features)(VirtIODevice *vdev, uint32_t val);
     void (*update_config)(VirtIODevice *vdev, uint8_t *config);
+    void (*reset)(VirtIODevice *vdev);
     VirtQueue vq[VIRTIO_PCI_QUEUE_MAX];
 };
 

-- 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [patch 2/2] QEMU/KVM: virtio-blk async IO (v3)
  2008-06-05  5:01 [patch 0/2] virtio-blk async IO (v3) Marcelo Tosatti
  2008-06-05  5:01 ` [patch 1/2] QEMU/KVM: provide a reset method for virtio Marcelo Tosatti
@ 2008-06-05  5:01 ` Marcelo Tosatti
  2008-06-05  7:50 ` [patch 0/2] " Avi Kivity
  2 siblings, 0 replies; 4+ messages in thread
From: Marcelo Tosatti @ 2008-06-05  5:01 UTC (permalink / raw)
  To: Avi Kivity, Anthony Liguori; +Cc: kvm, Gerd v. Egidy, Marcelo Tosatti

[-- Attachment #1: virtio-blk-async --]
[-- Type: text/plain, Size: 4492 bytes --]

virtio-blk should not use synchronous requests, as that can blocks vcpus
outside of guest mode for large periods of time for no reason.

Also report errors, which are currently ignored.

The generic block layer could complete AIO's before re-entering guest mode,
so that cached reads and writes can be reported ASAP.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

Index: kvm-userspace.vblk/qemu/hw/virtio-blk.c
===================================================================
--- kvm-userspace.vblk.orig/qemu/hw/virtio-blk.c
+++ kvm-userspace.vblk/qemu/hw/virtio-blk.c
@@ -79,16 +79,46 @@ static VirtIOBlock *to_virtio_blk(VirtIO
     return (VirtIOBlock *)vdev;
 }
 
+typedef struct VirtIOBlockReq
+{
+    VirtIODevice *vdev;
+    VirtQueue *vq;
+    struct iovec in_sg_status;
+    unsigned int pending;
+    unsigned int len;
+    unsigned int elem_idx;
+    int status;
+} VirtIOBlockReq;
+
+static void virtio_blk_rw_complete(void *opaque, int ret)
+{
+    VirtIOBlockReq *req = opaque;
+    struct virtio_blk_inhdr *in;
+    VirtQueueElement elem;
+
+    req->status |= ret;
+    if (--req->pending > 0)
+        return;
+
+    elem.index = req->elem_idx;
+    in = (void *)req->in_sg_status.iov_base;
+
+    in->status = req->status ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK;
+    virtqueue_push(req->vq, &elem, req->len);
+    virtio_notify(req->vdev, req->vq);
+    qemu_free(req);
+}
+
 static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 {
     VirtIOBlock *s = to_virtio_blk(vdev);
     VirtQueueElement elem;
+    VirtIOBlockReq *req;
     unsigned int count;
 
     while ((count = virtqueue_pop(vq, &elem)) != 0) {
 	struct virtio_blk_inhdr *in;
 	struct virtio_blk_outhdr *out;
-	unsigned int wlen;
 	off_t off;
 	int i;
 
@@ -103,41 +133,72 @@ static void virtio_blk_handle_output(Vir
 	    exit(1);
 	}
 
+	/*
+	 * FIXME: limit the number of in-flight requests
+	 */
+	req = qemu_malloc(sizeof(VirtIOBlockReq));
+	if (!req)
+	    return;
+	memset(req, 0, sizeof(*req));
+	memcpy(&req->in_sg_status, &elem.in_sg[elem.in_num - 1],
+	       sizeof(req->in_sg_status));
+	req->vdev = vdev;
+	req->vq = vq;
+	req->elem_idx = elem.index;
+
 	out = (void *)elem.out_sg[0].iov_base;
 	in = (void *)elem.in_sg[elem.in_num - 1].iov_base;
 	off = out->sector;
 
 	if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
-	    wlen = sizeof(*in);
+	    unsigned int len = sizeof(*in);
+
 	    in->status = VIRTIO_BLK_S_UNSUPP;
+	    virtqueue_push(vq, &elem, len);
+	    virtio_notify(vdev, vq);
+	    qemu_free(req);
 	} else if (out->type & VIRTIO_BLK_T_OUT) {
-	    wlen = sizeof(*in);
+	    req->pending = elem.out_num - 1;
 
 	    for (i = 1; i < elem.out_num; i++) {
-		bdrv_write(s->bs, off,
+		req->len += elem.out_sg[i].iov_len;
+		bdrv_aio_write(s->bs, off,
 			   elem.out_sg[i].iov_base,
-			   elem.out_sg[i].iov_len / 512);
+			   elem.out_sg[i].iov_len / 512,
+			   virtio_blk_rw_complete,
+			   req);
 		off += elem.out_sg[i].iov_len / 512;
-	    }
-
-	    in->status = VIRTIO_BLK_S_OK;
+ 	    }
 	} else {
-	    wlen = sizeof(*in);
+	    req->pending = elem.in_num - 1;
 
 	    for (i = 0; i < elem.in_num - 1; i++) {
-		bdrv_read(s->bs, off,
+		req->len += elem.in_sg[i].iov_len;
+		bdrv_aio_read(s->bs, off,
 			  elem.in_sg[i].iov_base,
-			  elem.in_sg[i].iov_len / 512);
+			  elem.in_sg[i].iov_len / 512,
+			  virtio_blk_rw_complete,
+			  req);
 		off += elem.in_sg[i].iov_len / 512;
-		wlen += elem.in_sg[i].iov_len;
-	    }
-
-	    in->status = VIRTIO_BLK_S_OK;
+ 	    }
 	}
-
-	virtqueue_push(vq, &elem, wlen);
-	virtio_notify(vdev, vq);
     }
+    /*
+     * FIXME: Want to check for completions before returning to guest mode,
+     * so cached reads and writes are reported as quickly as possible. But
+     * that should be done in the generic block layer.
+     */
+}
+
+static void virtio_blk_reset(VirtIODevice *vdev)
+{
+    VirtIOBlock *s = to_virtio_blk(vdev);
+
+    /*
+     * This should cancel pending requests, but can't do nicely until there
+     * are per-device request lists.
+     */
+    qemu_aio_flush();
 }
 
 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
@@ -196,6 +257,7 @@ void *virtio_blk_init(PCIBus *bus, uint1
 
     s->vdev.update_config = virtio_blk_update_config;
     s->vdev.get_features = virtio_blk_get_features;
+    s->vdev.reset = virtio_blk_reset;
     s->bs = bs;
     bs->devfn = s->vdev.pci_dev.devfn;
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);

-- 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch 0/2] virtio-blk async IO (v3)
  2008-06-05  5:01 [patch 0/2] virtio-blk async IO (v3) Marcelo Tosatti
  2008-06-05  5:01 ` [patch 1/2] QEMU/KVM: provide a reset method for virtio Marcelo Tosatti
  2008-06-05  5:01 ` [patch 2/2] QEMU/KVM: virtio-blk async IO (v3) Marcelo Tosatti
@ 2008-06-05  7:50 ` Avi Kivity
  2 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2008-06-05  7:50 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Anthony Liguori, kvm, Gerd v. Egidy

Marcelo Tosatti wrote:
> Resending the virtio-blk async patches, now that the reason for Gerd's
> hangs are known.
>
> The above results are on host hot-cached data, cold-cache data workloads
> are the real winners, where the current code waits until each read
> request is finished before submitting the next one.
>   

Applied, thanks.


-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-06-05  7:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-05  5:01 [patch 0/2] virtio-blk async IO (v3) Marcelo Tosatti
2008-06-05  5:01 ` [patch 1/2] QEMU/KVM: provide a reset method for virtio Marcelo Tosatti
2008-06-05  5:01 ` [patch 2/2] QEMU/KVM: virtio-blk async IO (v3) Marcelo Tosatti
2008-06-05  7:50 ` [patch 0/2] " Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox