[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC v9 17/27] virtio-blk: Use guest notifier to raise inte
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [RFC v9 17/27] virtio-blk: Use guest notifier to raise interrupts |
Date: |
Wed, 18 Jul 2012 16:07:44 +0100 |
The data plane thread isn't allowed to call virtio_irq() directly
because that function is not thread-safe. Use the guest notifier just
like virtio-net to handle IRQs.
When MSI-X is in use and the vector is unmasked, the guest notifier
directly sets the IRQ inside the host kernel. If the vector is masked,
then QEMU's iothread needs to take note of the IRQ. If MSI-X is not in
use, then QEMU's iothread handles the IRQ and this will be slower than
synchronously calling notify_irq() from the data plane thread.
---
hw/virtio-blk.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index d75c187..bdff68a 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -73,6 +73,18 @@ static int get_raw_posix_fd_hack(VirtIOBlock *s)
return *(int*)s->bs->file->opaque;
}
+/* Raise an interrupt to signal guest, if necessary */
+static void virtio_blk_notify_guest(VirtIOBlock *s)
+{
+ /* Always notify when queue is empty (when feature acknowledge) */
+ if ((s->vring.vr.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) &&
+ (s->vring.vr.avail->idx != s->vring.last_avail_idx ||
+ !(s->vdev.guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY))))
+ return;
+
+ event_notifier_set(virtio_queue_get_guest_notifier(s->vq));
+}
+
static void complete_request(struct iocb *iocb, ssize_t ret, void *opaque)
{
VirtIOBlock *s = opaque;
@@ -154,7 +166,7 @@ static void process_request(IOQueue *ioq, struct iovec
iov[], unsigned int out_n
fdatasync(get_raw_posix_fd_hack(s));
inhdr->status = VIRTIO_BLK_S_OK;
vring_push(&s->vring, head, sizeof *inhdr);
- virtio_irq(s->vq);
+ virtio_blk_notify_guest(s);
}
return;
@@ -222,8 +234,7 @@ static bool handle_io(EventHandler *handler)
VirtIOBlock *s = container_of(handler, VirtIOBlock, io_handler);
if (ioq_run_completion(&s->ioqueue, complete_request, s) > 0) {
- /* TODO is this thread-safe and can it be done faster? */
- virtio_irq(s->vq);
+ virtio_blk_notify_guest(s);
}
/* If there were more requests than iovecs, the vring will not be empty yet
@@ -251,11 +262,17 @@ static void data_plane_start(VirtIOBlock *s)
vring_setup(&s->vring, &s->vdev, 0);
+ /* Set up guest notifier (irq) */
+ if (s->vdev.binding->set_guest_notifier(s->vdev.binding_opaque, 0, true)
!= 0) {
+ fprintf(stderr, "virtio-blk failed to set guest notifier, ensure
-enable-kvm is set\n");
+ exit(1);
+ }
+
event_poll_init(&s->event_poll);
/* Set up virtqueue notify */
if (s->vdev.binding->set_host_notifier(s->vdev.binding_opaque, 0, true) !=
0) {
- fprintf(stderr, "virtio-blk failed to set host notifier, ensure
-enable-kvm is set\n");
+ fprintf(stderr, "virtio-blk failed to set host notifier\n");
exit(1);
}
event_poll_add(&s->event_poll, &s->notify_handler,
@@ -296,6 +313,9 @@ static void data_plane_stop(VirtIOBlock *s)
s->vdev.binding->set_host_notifier(s->vdev.binding_opaque, 0, false);
event_poll_cleanup(&s->event_poll);
+
+ /* Clean up guest notifier (irq) */
+ s->vdev.binding->set_guest_notifier(s->vdev.binding_opaque, 0, false);
}
static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t val)
--
1.7.10.4
- [Qemu-devel] [RFC v9 18/27] virtio-blk: Call ioctl() directly instead of irqfd, (continued)
- [Qemu-devel] [RFC v9 21/27] virtio-blk: Add basic request merging, Stefan Hajnoczi, 2012/07/18
- [Qemu-devel] [RFC v9 20/27] virtio-blk: Add ioscheduler to detect mergable requests, Stefan Hajnoczi, 2012/07/18
- [Qemu-devel] [RFC v9 26/27] msix: use upstream kvm_irqchip_set_irq(), Stefan Hajnoczi, 2012/07/18
- [Qemu-devel] [RFC v9 19/27] virtio-blk: Disable guest->host notifies while processing vring, Stefan Hajnoczi, 2012/07/18
- [Qemu-devel] [RFC v9 27/27] virtio-blk: add EVENT_IDX support to dataplane, Stefan Hajnoczi, 2012/07/18
- [Qemu-devel] [RFC v9 24/27] virtio-blk: fix incorrect length, Stefan Hajnoczi, 2012/07/18
- [Qemu-devel] [RFC v9 17/27] virtio-blk: Use guest notifier to raise interrupts,
Stefan Hajnoczi <=
- [Qemu-devel] [RFC v9 25/27] msix: fix irqchip breakage in msix_try_notify_from_thread(), Stefan Hajnoczi, 2012/07/18
- [Qemu-devel] [RFC v9 22/27] virtio-blk: Fix request merging, Stefan Hajnoczi, 2012/07/18
- Re: [Qemu-devel] [RFC v9 00/27] virtio: virtio-blk data plane, Michael S. Tsirkin, 2012/07/18
- Re: [Qemu-devel] [RFC v9 00/27] virtio: virtio-blk data plane, Michael S. Tsirkin, 2012/07/18