From: Pavel Fedin <p.fedin@samsung.com>
To: qemu-devel@nongnu.org
Cc: 'Christian Borntraeger' <borntraeger@de.ibm.com>,
"'Michael S. Tsirkin'" <mst@redhat.com>
Subject: [Qemu-devel] [PATCH] virtio: Implement userspace forwarding for host notifiers
Date: Thu, 19 Nov 2015 12:50:49 +0300 [thread overview]
Message-ID: <011b01d122af$c60f7ce0$522e76a0$@samsung.com> (raw)
If you happen to have a kernel with ioeventfd support enabled, but
missing support for them in KVM, and you attempt to enable vhost by
setting vhost=on, qemu aborts with error:
kvm_mem_ioeventfd_add: error adding ioeventfd: Function not implemented
This patch adds a mechanism which allows to emulate KVM binding by
triggering the related notifiers via the userspace. The first time the
emulation is used, a warning is displayed, so that the user knows about
potential performance impact:
2015-11-19T09:35:16.618380Z qemu-system-aarch64: KVM does not support eventfd binding, using userspace event forwarding (slow)
This problem can be observed with libvirt, which checks for /dev/vhost-net
availability and just inserts "vhost=on" automatically in this case; on an
ARM64 system using stock kernel 3.18.0 with CONFIG_IOEVENTFD enabled in
expert settings.
Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
---
hw/virtio/virtio-mmio.c | 15 +++++++++---
hw/virtio/virtio-pci.c | 61 ++++++++++++++++++++++++++--------------------
hw/virtio/virtio.c | 24 +++++++++++++++++-
include/hw/virtio/virtio.h | 1 +
4 files changed, 69 insertions(+), 32 deletions(-)
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 16621fa..69d4cbc 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -110,11 +110,18 @@ static int virtio_mmio_set_host_notifier_internal(VirtIOMMIOProxy *proxy,
return r;
}
virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
- memory_region_add_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4,
- true, n, notifier);
+
+ if (kvm_eventfds_enabled()) {
+ memory_region_add_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4,
+ true, n, notifier);
+ } else if (!set_handler) {
+ virtio_queue_set_host_notifier_forwarding(vq);
+ }
} else {
- memory_region_del_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4,
- true, n, notifier);
+ if (kvm_eventfds_enabled()) {
+ memory_region_del_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4,
+ true, n, notifier);
+ }
virtio_queue_set_host_notifier_fd_handler(vq, false, false);
event_notifier_cleanup(notifier);
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 96be4fd..b27a630 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -293,41 +293,48 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
return r;
}
virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
- if (modern) {
- if (fast_mmio) {
- memory_region_add_eventfd(modern_mr, modern_addr, 0,
- false, n, notifier);
- } else {
- memory_region_add_eventfd(modern_mr, modern_addr, 2,
- false, n, notifier);
+
+ if (kvm_eventfds_enabled()) {
+ if (modern) {
+ if (fast_mmio) {
+ memory_region_add_eventfd(modern_mr, modern_addr, 0,
+ false, n, notifier);
+ } else {
+ memory_region_add_eventfd(modern_mr, modern_addr, 2,
+ false, n, notifier);
+ }
+ if (modern_pio) {
+ memory_region_add_eventfd(modern_notify_mr, 0, 2,
+ true, n, notifier);
+ }
}
- if (modern_pio) {
- memory_region_add_eventfd(modern_notify_mr, 0, 2,
- true, n, notifier);
+ if (legacy) {
+ memory_region_add_eventfd(legacy_mr, legacy_addr, 2,
+ true, n, notifier);
}
- }
- if (legacy) {
- memory_region_add_eventfd(legacy_mr, legacy_addr, 2,
- true, n, notifier);
+ } else if (!set_handler) {
+ virtio_queue_set_host_notifier_forwarding(vq);
}
} else {
- if (modern) {
- if (fast_mmio) {
- memory_region_del_eventfd(modern_mr, modern_addr, 0,
- false, n, notifier);
- } else {
- memory_region_del_eventfd(modern_mr, modern_addr, 2,
- false, n, notifier);
+ if (kvm_eventfds_enabled()) {
+ if (modern) {
+ if (fast_mmio) {
+ memory_region_del_eventfd(modern_mr, modern_addr, 0,
+ false, n, notifier);
+ } else {
+ memory_region_del_eventfd(modern_mr, modern_addr, 2,
+ false, n, notifier);
+ }
+ if (modern_pio) {
+ memory_region_del_eventfd(modern_notify_mr, 0, 2,
+ true, n, notifier);
+ }
}
- if (modern_pio) {
- memory_region_del_eventfd(modern_notify_mr, 0, 2,
+ if (legacy) {
+ memory_region_del_eventfd(legacy_mr, legacy_addr, 2,
true, n, notifier);
}
}
- if (legacy) {
- memory_region_del_eventfd(legacy_mr, legacy_addr, 2,
- true, n, notifier);
- }
virtio_queue_set_host_notifier_fd_handler(vq, false, false);
event_notifier_cleanup(notifier);
}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 1edef59..6fe268f 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -89,6 +89,7 @@ struct VirtQueue
VirtIODevice *vdev;
EventNotifier guest_notifier;
EventNotifier host_notifier;
+ bool forward_host_notifier;
QLIST_ENTRY(VirtQueue) node;
};
@@ -969,7 +970,13 @@ void virtio_queue_notify_vq(VirtQueue *vq)
void virtio_queue_notify(VirtIODevice *vdev, int n)
{
- virtio_queue_notify_vq(&vdev->vq[n]);
+ VirtQueue *vq = &vdev->vq[n];
+
+ if (vq->forward_host_notifier) {
+ event_notifier_set(&vq->host_notifier);
+ } else {
+ virtio_queue_notify_vq(&vdev->vq[n]);
+ }
}
uint16_t virtio_queue_vector(VirtIODevice *vdev, int n)
@@ -1715,6 +1722,21 @@ void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
/* Test and clear notifier before after disabling event,
* in case poll callback didn't have time to run. */
virtio_queue_host_notifier_read(&vq->host_notifier);
+
+ vq->forward_host_notifier = false;
+ }
+}
+
+static bool forwarding_warning;
+
+void virtio_queue_set_host_notifier_forwarding(VirtQueue *vq)
+{
+ vq->forward_host_notifier = true;
+
+ if (!forwarding_warning) {
+ forwarding_warning = true;
+ error_report("KVM does not support eventfd binding, "
+ "using userspace event forwarding (slow)");
}
}
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 205fadf..f288ccb 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -245,6 +245,7 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
bool set_handler);
+void virtio_queue_set_host_notifier_forwarding(VirtQueue *vq);
void virtio_queue_notify_vq(VirtQueue *vq);
void virtio_irq(VirtQueue *vq);
VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
--
1.9.5.msysgit.0
next reply other threads:[~2015-11-19 9:51 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-19 9:50 Pavel Fedin [this message]
2015-11-19 9:56 ` [Qemu-devel] [PATCH] virtio: Implement userspace forwarding for host notifiers Christian Borntraeger
2015-11-19 10:18 ` Pavel Fedin
2015-11-19 11:41 ` Cornelia Huck
2015-11-19 12:02 ` Pavel Fedin
2015-11-19 12:05 ` Michael S. Tsirkin
2015-11-19 10:55 ` Michael S. Tsirkin
2015-11-19 11:44 ` Pavel Fedin
2015-11-19 12:01 ` Michael S. Tsirkin
2015-11-19 12:06 ` Paolo Bonzini
2015-11-19 12:10 ` Michael S. Tsirkin
2015-11-19 12:17 ` Pavel Fedin
2015-11-19 12:31 ` Paolo Bonzini
2015-11-19 12:55 ` Cornelia Huck
2015-11-19 16:03 ` Pavel Fedin
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='011b01d122af$c60f7ce0$522e76a0$@samsung.com' \
--to=p.fedin@samsung.com \
--cc=borntraeger@de.ibm.com \
--cc=mst@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.