svn commit: r245709 - in projects/virtio/sys/dev/virtio: . pci
Bryan Venteicher
bryanv at FreeBSD.org
Mon Jan 21 06:42:58 UTC 2013
Author: bryanv
Date: Mon Jan 21 06:42:56 2013
New Revision: 245709
URL: http://svnweb.freebsd.org/changeset/base/245709
Log:
virtio: Add support for ithread(9)
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.
Currently, the ithreads are just scheduling the device's taskqueue
as before. The taskqueues in each driver will be removed in
subsequent commits.
Approved by: grehan (implicit)
Modified:
projects/virtio/sys/dev/virtio/pci/virtio_pci.c
projects/virtio/sys/dev/virtio/virtio_if.m
projects/virtio/sys/dev/virtio/virtqueue.c
projects/virtio/sys/dev/virtio/virtqueue.h
Modified: projects/virtio/sys/dev/virtio/pci/virtio_pci.c
==============================================================================
--- projects/virtio/sys/dev/virtio/pci/virtio_pci.c Mon Jan 21 04:06:04 2013 (r245708)
+++ projects/virtio/sys/dev/virtio/pci/virtio_pci.c Mon Jan 21 06:42:56 2013 (r245709)
@@ -160,10 +160,12 @@ static void vtpci_reset(struct vtpci_sof
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 vtpc
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
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
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
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_soft
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);
}
Modified: projects/virtio/sys/dev/virtio/virtio_if.m
==============================================================================
--- projects/virtio/sys/dev/virtio/virtio_if.m Mon Jan 21 04:06:04 2013 (r245708)
+++ projects/virtio/sys/dev/virtio/virtio_if.m Mon Jan 21 06:42:56 2013 (r245709)
@@ -33,8 +33,7 @@ CODE {
static int
virtio_default_config_change(device_t dev)
{
- /* Return that we've handled the change. */
- return (1);
+ return (0);
}
};
Modified: projects/virtio/sys/dev/virtio/virtqueue.c
==============================================================================
--- projects/virtio/sys/dev/virtio/virtqueue.c Mon Jan 21 04:06:04 2013 (r245708)
+++ projects/virtio/sys/dev/virtio/virtqueue.c Mon Jan 21 06:42:56 2013 (r245709)
@@ -414,18 +414,27 @@ virtqueue_nused(struct virtqueue *vq)
}
int
-virtqueue_intr(struct virtqueue *vq)
+virtqueue_intr_filter(struct virtqueue *vq)
{
- if (vq->vq_intrhand == NULL ||
- vq->vq_used_cons_idx == vq->vq_ring.used->idx)
+ if (__predict_false(vq->vq_intrhand == NULL))
+ return (0);
+ if (vq->vq_used_cons_idx == vq->vq_ring.used->idx)
return (0);
- vq->vq_intrhand(vq->vq_intrhand_arg);
+ virtqueue_disable_intr(vq);
return (1);
}
+void
+virtqueue_intr(struct virtqueue *vq)
+{
+
+ if (__predict_true(vq->vq_intrhand != NULL))
+ vq->vq_intrhand(vq->vq_intrhand_arg);
+}
+
int
virtqueue_enable_intr(struct virtqueue *vq)
{
Modified: projects/virtio/sys/dev/virtio/virtqueue.h
==============================================================================
--- projects/virtio/sys/dev/virtio/virtqueue.h Mon Jan 21 04:06:04 2013 (r245708)
+++ projects/virtio/sys/dev/virtio/virtqueue.h Mon Jan 21 06:42:56 2013 (r245709)
@@ -70,7 +70,8 @@ void *virtqueue_drain(struct virtqueue *
void virtqueue_free(struct virtqueue *vq);
int virtqueue_reinit(struct virtqueue *vq, uint16_t size);
-int virtqueue_intr(struct virtqueue *vq);
+int virtqueue_intr_filter(struct virtqueue *vq);
+void virtqueue_intr(struct virtqueue *vq);
int virtqueue_enable_intr(struct virtqueue *vq);
int virtqueue_postpone_intr(struct virtqueue *vq);
void virtqueue_disable_intr(struct virtqueue *vq);
More information about the svn-src-projects
mailing list