From owner-svn-src-projects@FreeBSD.ORG Tue Jan 29 07:46:23 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 3EE6DF1D; Tue, 29 Jan 2013 07:46:23 +0000 (UTC) (envelope-from bryanv@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 224F3DA3; Tue, 29 Jan 2013 07:46:23 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r0T7kN3h011063; Tue, 29 Jan 2013 07:46:23 GMT (envelope-from bryanv@svn.freebsd.org) Received: (from bryanv@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r0T7kMSo011061; Tue, 29 Jan 2013 07:46:22 GMT (envelope-from bryanv@svn.freebsd.org) Message-Id: <201301290746.r0T7kMSo011061@svn.freebsd.org> From: Bryan Venteicher Date: Tue, 29 Jan 2013 07:46:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r246066 - in projects/virtio/sys/dev/virtio: . pci X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Jan 2013 07:46:23 -0000 Author: bryanv Date: Tue Jan 29 07:46:22 2013 New Revision: 246066 URL: http://svnweb.freebsd.org/changeset/base/246066 Log: virtio_pci: Dynamically allocate the virtqueue array For network multiqueue, we may need to support many queues so it is impractical to have a static array in the VirtIO PCI's softc. Approved by: grehan (implicit) Modified: projects/virtio/sys/dev/virtio/pci/virtio_pci.c projects/virtio/sys/dev/virtio/virtio.h Modified: projects/virtio/sys/dev/virtio/pci/virtio_pci.c ============================================================================== --- projects/virtio/sys/dev/virtio/pci/virtio_pci.c Tue Jan 29 07:44:35 2013 (r246065) +++ projects/virtio/sys/dev/virtio/pci/virtio_pci.c Tue Jan 29 07:46:22 2013 (r246066) @@ -57,6 +57,11 @@ struct vtpci_interrupt { void *vti_handler; }; +struct vtpci_virtqueue { + struct virtqueue *vtv_vq; + int vtv_no_intr; +}; + struct vtpci_softc { device_t vtpci_dev; struct resource *vtpci_res; @@ -75,6 +80,9 @@ struct vtpci_softc { device_t vtpci_child_dev; struct virtio_feature_desc *vtpci_child_feat_desc; + int vtpci_nvqs; + struct vtpci_virtqueue *vtpci_vqs; + /* * Ideally, each virtqueue that the driver provides a callback for will * receive its own MSIX vector. If there are not sufficient vectors @@ -87,14 +95,7 @@ struct vtpci_softc { */ struct vtpci_interrupt vtpci_device_interrupt; struct vtpci_interrupt *vtpci_msix_vq_interrupts; - - int vtpci_nvqs; int vtpci_nmsix_resources; - - struct vtpci_virtqueue { - struct virtqueue *vqx_vq; - int vqx_no_intr; - } vtpci_vqx[VIRTIO_MAX_VIRTQUEUES]; }; static int vtpci_probe(device_t); @@ -482,14 +483,19 @@ vtpci_alloc_virtqueues(device_t dev, int if (sc->vtpci_nvqs != 0) return (EALREADY); - if (nvqs <= 0 || nvqs > VIRTIO_MAX_VIRTQUEUES) + if (nvqs <= 0) return (EINVAL); if (flags & VIRTIO_ALLOC_VQS_DISABLE_MSIX) sc->vtpci_flags |= VTPCI_FLAG_NO_MSIX; + sc->vtpci_vqs = malloc(nvqs * sizeof(struct vtpci_virtqueue), + M_DEVBUF, M_NOWAIT | M_ZERO); + if (sc->vtpci_vqs == NULL) + return (ENOMEM); + for (idx = 0; idx < nvqs; idx++) { - vqx = &sc->vtpci_vqx[idx]; + vqx = &sc->vtpci_vqs[idx]; info = &vq_info[idx]; vtpci_select_virtqueue(sc, idx); @@ -506,8 +512,8 @@ vtpci_alloc_virtqueues(device_t dev, int vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN, virtqueue_paddr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT); - vqx->vqx_vq = *info->vqai_vq = vq; - vqx->vqx_no_intr = info->vqai_intr == NULL; + vqx->vtv_vq = *info->vqai_vq = vq; + vqx->vtv_no_intr = info->vqai_intr == NULL; sc->vtpci_nvqs++; } @@ -813,7 +819,7 @@ vtpci_alloc_intr_msix_pervq(struct vtpci return (ENOTSUP); for (nvectors = 0, i = 0; i < sc->vtpci_nvqs; i++) { - if (sc->vtpci_vqx[i].vqx_no_intr == 0) + if (sc->vtpci_vqs[i].vtv_no_intr == 0) nvectors++; } @@ -953,13 +959,13 @@ vtpci_setup_pervq_msix_interrupts(struct intr = sc->vtpci_msix_vq_interrupts; for (i = 0; i < sc->vtpci_nvqs; i++) { - vqx = &sc->vtpci_vqx[i]; + vqx = &sc->vtpci_vqs[i]; - if (vqx->vqx_no_intr) + if (vqx->vtv_no_intr) continue; error = bus_setup_intr(sc->vtpci_dev, intr->vti_irq, type, - vtpci_vq_intr_filter, vtpci_vq_intr, vqx->vqx_vq, + vtpci_vq_intr_filter, vtpci_vq_intr, vqx->vtv_vq, &intr->vti_handler); if (error) return (error); @@ -1065,7 +1071,7 @@ vtpci_set_host_msix_vectors(struct vtpci for (idx = 0; idx < sc->vtpci_nvqs; idx++) { vtpci_select_virtqueue(sc, idx); - if (sc->vtpci_vqx[idx].vqx_no_intr) + if (sc->vtpci_vqs[idx].vtv_no_intr) tintr = NULL; else tintr = intr; @@ -1093,8 +1099,8 @@ vtpci_reinit_virtqueue(struct vtpci_soft int error; uint16_t size; - vqx = &sc->vtpci_vqx[idx]; - vq = vqx->vqx_vq; + vqx = &sc->vtpci_vqs[idx]; + vq = vqx->vtv_vq; KASSERT(vq != NULL, ("%s: vq %d not allocated", __func__, idx)); @@ -1166,12 +1172,14 @@ vtpci_free_virtqueues(struct vtpci_softc int i; for (i = 0; i < sc->vtpci_nvqs; i++) { - vqx = &sc->vtpci_vqx[i]; + vqx = &sc->vtpci_vqs[i]; - virtqueue_free(vqx->vqx_vq); - vqx->vqx_vq = NULL; + virtqueue_free(vqx->vtv_vq); + vqx->vtv_vq = NULL; } + free(sc->vtpci_vqs, M_DEVBUF); + sc->vtpci_vqs = NULL; sc->vtpci_nvqs = 0; } @@ -1229,7 +1237,7 @@ vtpci_legacy_intr(void *xsc) uint8_t isr; sc = xsc; - vqx = &sc->vtpci_vqx[0]; + vqx = &sc->vtpci_vqs[0]; /* Reading the ISR also clears it. */ isr = vtpci_read_config_1(sc, VIRTIO_PCI_ISR); @@ -1239,7 +1247,7 @@ vtpci_legacy_intr(void *xsc) if (isr & VIRTIO_PCI_ISR_INTR) { for (i = 0; i < sc->vtpci_nvqs; i++, vqx++) - virtqueue_intr(vqx->vqx_vq); + virtqueue_intr(vqx->vtv_vq); } } @@ -1252,10 +1260,10 @@ vtpci_vq_shared_intr_filter(void *xsc) rc = 0; sc = xsc; - vqx = &sc->vtpci_vqx[0]; + vqx = &sc->vtpci_vqs[0]; for (i = 0; i < sc->vtpci_nvqs; i++, vqx++) - rc |= virtqueue_intr_filter(vqx->vqx_vq); + rc |= virtqueue_intr_filter(vqx->vtv_vq); return (rc ? FILTER_SCHEDULE_THREAD : FILTER_STRAY); } @@ -1268,10 +1276,10 @@ vtpci_vq_shared_intr(void *xsc) int i; sc = xsc; - vqx = &sc->vtpci_vqx[0]; + vqx = &sc->vtpci_vqs[0]; for (i = 0; i < sc->vtpci_nvqs; i++, vqx++) - virtqueue_intr(vqx->vqx_vq); + virtqueue_intr(vqx->vtv_vq); } static int Modified: projects/virtio/sys/dev/virtio/virtio.h ============================================================================== --- projects/virtio/sys/dev/virtio/virtio.h Tue Jan 29 07:44:35 2013 (r246065) +++ projects/virtio/sys/dev/virtio/virtio.h Tue Jan 29 07:46:22 2013 (r246066) @@ -71,11 +71,6 @@ struct vq_alloc_info; #define VIRTIO_TRANSPORT_F_END 32 /* - * Maximum number of virtqueues per device. - */ -#define VIRTIO_MAX_VIRTQUEUES 8 - -/* * Each virtqueue indirect descriptor list must be physically contiguous. * To allow us to malloc(9) each list individually, limit the number * supported to what will fit in one page. With 4KB pages, this is a limit