summaryrefslogtreecommitdiffstats
path: root/sys/dev/virtio/pci
diff options
context:
space:
mode:
authorbryanv <bryanv@FreeBSD.org>2013-07-04 17:50:11 +0000
committerbryanv <bryanv@FreeBSD.org>2013-07-04 17:50:11 +0000
commitecdd9ae0054b1b8b776661b78e8a20fb0973775d (patch)
treeadfa592c287e8e552c48a18adac66fc0d37fffd6 /sys/dev/virtio/pci
parentbe7c32fd304a8aa87a4cd877782d254092d1282f (diff)
downloadFreeBSD-src-ecdd9ae0054b1b8b776661b78e8a20fb0973775d.zip
FreeBSD-src-ecdd9ae0054b1b8b776661b78e8a20fb0973775d.tar.gz
Convert VirtIO to use ithreads instead of taskqueues
Contains projects/virtio commits: r245709: Each VirtIO device was scheduling its own taskqueue(9) to do the off-level interrupt handling. ithreads(9) is the more nature way to do this. The primary motivation for this work to better support network multiqueue. r245710: virtio: Change virtqueue intr handlers to return void r245711: virtio_blk: Remove interrupt taskqueue r245721: vtnet: Remove interrupt taskqueue r245722: virtio_scsi: Remove interrupt taskqueue r245747: vtnet: Remove taskqueue fields missed in r245721 MFC after: 1 month
Diffstat (limited to 'sys/dev/virtio/pci')
-rw-r--r--sys/dev/virtio/pci/virtio_pci.c88
1 files changed, 52 insertions, 36 deletions
diff --git a/sys/dev/virtio/pci/virtio_pci.c b/sys/dev/virtio/pci/virtio_pci.c
index 917ca84..02a9d23 100644
--- a/sys/dev/virtio/pci/virtio_pci.c
+++ b/sys/dev/virtio/pci/virtio_pci.c
@@ -160,10 +160,12 @@ static void vtpci_reset(struct vtpci_softc *);
static void vtpci_select_virtqueue(struct vtpci_softc *, int);
-static int vtpci_legacy_intr(void *);
-static int vtpci_vq_shared_intr(void *);
-static int vtpci_vq_intr(void *);
-static int vtpci_config_intr(void *);
+static void vtpci_legacy_intr(void *);
+static int vtpci_vq_shared_intr_filter(void *);
+static void vtpci_vq_shared_intr(void *);
+static int vtpci_vq_intr_filter(void *);
+static void vtpci_vq_intr(void *);
+static void vtpci_config_intr(void *);
#define vtpci_setup_msi_interrupt vtpci_setup_legacy_interrupt
@@ -932,7 +934,7 @@ vtpci_setup_legacy_interrupt(struct vtpci_softc *sc, enum intr_type type)
dev = sc->vtpci_dev;
ires = &sc->vtpci_intr_res[0];
- error = bus_setup_intr(dev, ires->irq, type, vtpci_legacy_intr, NULL,
+ error = bus_setup_intr(dev, ires->irq, type, NULL, vtpci_legacy_intr,
sc, &ires->intrhand);
return (error);
@@ -949,11 +951,11 @@ vtpci_setup_msix_interrupts(struct vtpci_softc *sc, enum intr_type type)
dev = sc->vtpci_dev;
/*
- * The first resource is used for configuration changed interrupts.
+ * The first MSIX vector is used for configuration changed interrupts.
*/
ires = &sc->vtpci_intr_res[0];
- error = bus_setup_intr(dev, ires->irq, type, vtpci_config_intr,
- NULL, sc, &ires->intrhand);
+ error = bus_setup_intr(dev, ires->irq, type, NULL, vtpci_config_intr,
+ sc, &ires->intrhand);
if (error)
return (error);
@@ -961,13 +963,9 @@ vtpci_setup_msix_interrupts(struct vtpci_softc *sc, enum intr_type type)
ires = &sc->vtpci_intr_res[1];
error = bus_setup_intr(dev, ires->irq, type,
- vtpci_vq_shared_intr, NULL, sc, &ires->intrhand);
- if (error)
- return (error);
+ vtpci_vq_shared_intr_filter, vtpci_vq_shared_intr, sc,
+ &ires->intrhand);
} else {
- /*
- * Each remaining resource is assigned to a specific virtqueue.
- */
for (i = 0; i < sc->vtpci_nvqs; i++) {
vqx = &sc->vtpci_vqx[i];
if (vqx->ires_idx < 1)
@@ -975,17 +973,17 @@ vtpci_setup_msix_interrupts(struct vtpci_softc *sc, enum intr_type type)
ires = &sc->vtpci_intr_res[vqx->ires_idx];
error = bus_setup_intr(dev, ires->irq, type,
- vtpci_vq_intr, NULL, vqx->vq, &ires->intrhand);
+ vtpci_vq_intr_filter, vtpci_vq_intr, vqx->vq,
+ &ires->intrhand);
if (error)
- return (error);
+ break;
}
}
- error = vtpci_set_host_msix_vectors(sc);
- if (error)
- return (error);
+ if (error == 0)
+ error = vtpci_set_host_msix_vectors(sc);
- return (0);
+ return (error);
}
static int
@@ -1191,7 +1189,7 @@ vtpci_select_virtqueue(struct vtpci_softc *sc, int idx)
vtpci_write_config_2(sc, VIRTIO_PCI_QUEUE_SEL, idx);
}
-static int
+static void
vtpci_legacy_intr(void *xsc)
{
struct vtpci_softc *sc;
@@ -1208,15 +1206,14 @@ vtpci_legacy_intr(void *xsc)
if (isr & VIRTIO_PCI_ISR_CONFIG)
vtpci_config_intr(sc);
- if (isr & VIRTIO_PCI_ISR_INTR)
+ if (isr & VIRTIO_PCI_ISR_INTR) {
for (i = 0; i < sc->vtpci_nvqs; i++, vqx++)
virtqueue_intr(vqx->vq);
-
- return (isr ? FILTER_HANDLED : FILTER_STRAY);
+ }
}
static int
-vtpci_vq_shared_intr(void *xsc)
+vtpci_vq_shared_intr_filter(void *xsc)
{
struct vtpci_softc *sc;
struct vtpci_virtqueue *vqx;
@@ -1227,36 +1224,55 @@ vtpci_vq_shared_intr(void *xsc)
vqx = &sc->vtpci_vqx[0];
for (i = 0; i < sc->vtpci_nvqs; i++, vqx++)
- rc |= virtqueue_intr(vqx->vq);
+ rc |= virtqueue_intr_filter(vqx->vq);
+
+ return (rc ? FILTER_SCHEDULE_THREAD : FILTER_STRAY);
+}
+
+static void
+vtpci_vq_shared_intr(void *xsc)
+{
+ struct vtpci_softc *sc;
+ struct vtpci_virtqueue *vqx;
+ int i;
+
+ sc = xsc;
+ vqx = &sc->vtpci_vqx[0];
- return (rc ? FILTER_HANDLED : FILTER_STRAY);
+ for (i = 0; i < sc->vtpci_nvqs; i++, vqx++)
+ virtqueue_intr(vqx->vq);
}
static int
-vtpci_vq_intr(void *xvq)
+vtpci_vq_intr_filter(void *xvq)
{
struct virtqueue *vq;
int rc;
vq = xvq;
- rc = virtqueue_intr(vq);
+ rc = virtqueue_intr_filter(vq);
- return (rc ? FILTER_HANDLED : FILTER_STRAY);
+ return (rc ? FILTER_SCHEDULE_THREAD : FILTER_STRAY);
}
-static int
+static void
+vtpci_vq_intr(void *xvq)
+{
+ struct virtqueue *vq;
+
+ vq = xvq;
+ virtqueue_intr(vq);
+}
+
+static void
vtpci_config_intr(void *xsc)
{
struct vtpci_softc *sc;
device_t child;
- int rc;
- rc = 0;
sc = xsc;
child = sc->vtpci_child_dev;
if (child != NULL)
- rc = VIRTIO_CONFIG_CHANGE(child);
-
- return (rc ? FILTER_HANDLED : FILTER_STRAY);
+ VIRTIO_CONFIG_CHANGE(child);
}
OpenPOWER on IntegriCloud