* [Qemu-devel] [PATCHv2] virtio: don't waste irqfds on control vqs
@ 2012-12-20 16:29 Michael S. Tsirkin
0 siblings, 0 replies; only message in thread
From: Michael S. Tsirkin @ 2012-12-20 16:29 UTC (permalink / raw)
To: qemu-devel
Cc: Anthony Liguori, Stefan Hajnoczi, Michael S. Tsirkin, Jan Kiszka,
Paolo Bonzini, Richard Henderson
Pass nvqs to set_guest_notifiers. This makes it possible to
save on irqfds by not allocating one for the control vq
for virtio-net.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
Changes from v1:
- fix poll implementation to not use uninitialized notifiers
- verify correct API usage by checking same nvqs
is passed on assign/deassign
hw/vhost.c | 10 +++++++---
hw/virtio-pci.c | 15 ++++++++++++---
hw/virtio-pci.h | 1 +
hw/virtio.h | 2 +-
4 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/hw/vhost.c b/hw/vhost.c
index 4e1cb47..b6d73ca 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -879,7 +879,9 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
goto fail;
}
- r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, true);
+ r = vdev->binding->set_guest_notifiers(vdev->binding_opaque,
+ hdev->nvqs,
+ true);
if (r < 0) {
fprintf(stderr, "Error binding guest notifier: %d\n", -r);
goto fail_notifiers;
@@ -929,7 +931,7 @@ fail_vq:
}
fail_mem:
fail_features:
- vdev->binding->set_guest_notifiers(vdev->binding_opaque, false);
+ vdev->binding->set_guest_notifiers(vdev->binding_opaque, hdev->nvqs, false);
fail_notifiers:
fail:
return r;
@@ -950,7 +952,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
vhost_sync_dirty_bitmap(hdev, &hdev->mem_sections[i],
0, (hwaddr)~0x0ull);
}
- r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, false);
+ r = vdev->binding->set_guest_notifiers(vdev->binding_opaque,
+ hdev->nvqs,
+ false);
if (r < 0) {
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
fflush(stderr);
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 72101d3..21bf911 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -587,7 +587,7 @@ static void kvm_virtio_pci_vector_poll(PCIDevice *dev,
EventNotifier *notifier;
VirtQueue *vq;
- for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
+ for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
if (!virtio_queue_get_num(vdev, queue_no)) {
break;
}
@@ -631,7 +631,7 @@ static bool virtio_pci_query_guest_notifiers(DeviceState *d)
return msix_enabled(&proxy->pci_dev);
}
-static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign)
+static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
{
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
VirtIODevice *vdev = proxy->vdev;
@@ -639,6 +639,13 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign)
bool with_irqfd = msix_enabled(&proxy->pci_dev) &&
kvm_msi_via_irqfd_enabled();
+ nvqs = MIN(nvqs, VIRTIO_PCI_QUEUE_MAX);
+
+ /* When deassigning, pass a consistent nvqs value
+ * to avoid leaking notifiers.
+ */
+ assert(assign || nvqs == proxy->nvqs_with_notifiers);
+
/* Must unset vector notifier while guest notifier is still assigned */
if (with_irqfd && !assign) {
msix_unset_vector_notifiers(&proxy->pci_dev);
@@ -646,7 +653,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign)
proxy->vector_irqfd = NULL;
}
- for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
+ for (n = 0; n < nvqs; n++) {
if (!virtio_queue_get_num(vdev, n)) {
break;
}
@@ -672,6 +679,8 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign)
}
}
+ proxy->nvqs_with_notifiers = nvqs;
+
return 0;
assign_error:
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index b58d9a2..b0f17e2 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -51,6 +51,7 @@ typedef struct {
bool ioeventfd_disabled;
bool ioeventfd_started;
VirtIOIRQFD *vector_irqfd;
+ int nvqs_with_notifiers;
} VirtIOPCIProxy;
void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
diff --git a/hw/virtio.h b/hw/virtio.h
index 75b3e3e..1a21c84 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -99,7 +99,7 @@ typedef struct {
int (*load_done)(DeviceState *d, QEMUFile *f);
unsigned (*get_features)(DeviceState *d);
bool (*query_guest_notifiers)(DeviceState *d);
- int (*set_guest_notifiers)(DeviceState *d, bool assigned);
+ int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assigned);
int (*set_host_notifier)(DeviceState *d, int n, bool assigned);
void (*vmstate_change)(DeviceState *d, bool running);
} VirtIOBindings;
--
MST
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2012-12-20 16:26 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-20 16:29 [Qemu-devel] [PATCHv2] virtio: don't waste irqfds on control vqs Michael S. Tsirkin
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.