Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Jan 2013 07:46:22 +0000 (UTC)
From:      Bryan Venteicher <bryanv@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r246066 - in projects/virtio/sys/dev/virtio: . pci
Message-ID:  <201301290746.r0T7kMSo011061@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201301290746.r0T7kMSo011061>