mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 20:19:44 +00:00
virtio: don't waste irqfds on control vqs
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>
This commit is contained in:
parent
8e4a424b30
commit
2d620f593d
10
hw/vhost.c
10
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);
|
||||
|
@ -535,7 +535,7 @@ static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector,
|
||||
VirtIODevice *vdev = proxy->vdev;
|
||||
int ret, queue_no;
|
||||
|
||||
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;
|
||||
}
|
||||
@ -565,7 +565,7 @@ static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector)
|
||||
VirtIODevice *vdev = proxy->vdev;
|
||||
int queue_no;
|
||||
|
||||
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;
|
||||
}
|
||||
@ -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,15 @@ 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);
|
||||
|
||||
proxy->nvqs_with_notifiers = nvqs;
|
||||
|
||||
/* Must unset vector notifier while guest notifier is still assigned */
|
||||
if (proxy->vector_irqfd && !assign) {
|
||||
msix_unset_vector_notifiers(&proxy->pci_dev);
|
||||
@ -646,7 +655,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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user