From patchwork Wed Dec 26 10:52:19 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 208160 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A25A72C00BE for ; Wed, 26 Dec 2012 21:49:56 +1100 (EST) Received: from localhost ([::1]:38923 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TnoYc-00084z-BM for incoming@patchwork.ozlabs.org; Wed, 26 Dec 2012 05:49:54 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52838) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TnoXu-0006m1-Pe for qemu-devel@nongnu.org; Wed, 26 Dec 2012 05:49:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TnoXr-0004aN-4e for qemu-devel@nongnu.org; Wed, 26 Dec 2012 05:49:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38613) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TnoXq-0004aG-TG for qemu-devel@nongnu.org; Wed, 26 Dec 2012 05:49:07 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qBQAn6mV013878 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 26 Dec 2012 05:49:06 -0500 Received: from redhat.com (vpn1-4-149.ams2.redhat.com [10.36.4.149]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id qBQAn4YA015628; Wed, 26 Dec 2012 05:49:04 -0500 Date: Wed, 26 Dec 2012 12:52:19 +0200 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org, asias@redhat.com, stefanha@redhat.com Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Mutt-Fcc: =sent X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 1/8] virtio: don't waste irqfds on control vqs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- hw/vhost.c | 10 +++++++--- hw/virtio-pci.c | 19 ++++++++++++++----- hw/virtio-pci.h | 1 + hw/virtio.h | 2 +- 4 files changed, 23 insertions(+), 9 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 af9a56c..3c258a4 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -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; } 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 1dec9dc..329b426 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;