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
This commit is contained in:
Bryan Venteicher 2013-07-04 17:50:11 +00:00
parent 61762e7dbc
commit 6632efe40d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=252702
10 changed files with 113 additions and 278 deletions

View file

@ -90,7 +90,7 @@ static int vtballoon_config_change(device_t);
static void vtballoon_negotiate_features(struct vtballoon_softc *);
static int vtballoon_alloc_virtqueues(struct vtballoon_softc *);
static int vtballoon_vq_intr(void *);
static void vtballoon_vq_intr(void *);
static void vtballoon_inflate(struct vtballoon_softc *, int);
static void vtballoon_deflate(struct vtballoon_softc *, int);
@ -300,7 +300,7 @@ vtballoon_alloc_virtqueues(struct vtballoon_softc *sc)
return (virtio_alloc_virtqueues(dev, 0, nvqs, vq_info));
}
static int
static void
vtballoon_vq_intr(void *xsc)
{
struct vtballoon_softc *sc;
@ -310,8 +310,6 @@ vtballoon_vq_intr(void *xsc)
VTBALLOON_LOCK(sc);
wakeup_one(sc);
VTBALLOON_UNLOCK(sc);
return (1);
}
static void

View file

@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <geom/geom_disk.h>
@ -85,9 +84,6 @@ struct vtblk_softc {
vtblk_req_ready;
struct vtblk_request *vtblk_req_ordered;
struct taskqueue *vtblk_tq;
struct task vtblk_intr_task;
int vtblk_max_nsegs;
int vtblk_request_count;
@ -138,8 +134,7 @@ static struct vtblk_request * vtblk_bio_request(struct vtblk_softc *);
static int vtblk_execute_request(struct vtblk_softc *,
struct vtblk_request *);
static int vtblk_vq_intr(void *);
static void vtblk_intr_task(void *, int);
static void vtblk_vq_intr(void *);
static void vtblk_stop(struct vtblk_softc *);
@ -333,24 +328,12 @@ vtblk_attach(device_t dev)
vtblk_alloc_disk(sc, &blkcfg);
TASK_INIT(&sc->vtblk_intr_task, 0, vtblk_intr_task, sc);
sc->vtblk_tq = taskqueue_create_fast("vtblk_taskq", M_NOWAIT,
taskqueue_thread_enqueue, &sc->vtblk_tq);
if (sc->vtblk_tq == NULL) {
error = ENOMEM;
device_printf(dev, "cannot allocate taskqueue\n");
goto fail;
}
error = virtio_setup_intr(dev, INTR_TYPE_BIO | INTR_ENTROPY);
if (error) {
device_printf(dev, "cannot setup virtqueue interrupt\n");
goto fail;
}
taskqueue_start_threads(&sc->vtblk_tq, 1, PI_DISK, "%s taskq",
device_get_nameunit(dev));
vtblk_create_disk(sc);
virtqueue_enable_intr(sc->vtblk_vq);
@ -375,12 +358,6 @@ vtblk_detach(device_t dev)
vtblk_stop(sc);
VTBLK_UNLOCK(sc);
if (sc->vtblk_tq != NULL) {
taskqueue_drain(sc->vtblk_tq, &sc->vtblk_intr_task);
taskqueue_free(sc->vtblk_tq);
sc->vtblk_tq = NULL;
}
vtblk_drain(sc);
if (sc->vtblk_disk != NULL) {
@ -834,28 +811,16 @@ vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req)
return (error);
}
static int
vtblk_vq_intr(void *xsc)
{
struct vtblk_softc *sc;
sc = xsc;
virtqueue_disable_intr(sc->vtblk_vq);
taskqueue_enqueue_fast(sc->vtblk_tq, &sc->vtblk_intr_task);
return (1);
}
static void
vtblk_intr_task(void *arg, int pending)
vtblk_vq_intr(void *xsc)
{
struct vtblk_softc *sc;
struct virtqueue *vq;
sc = arg;
sc = xsc;
vq = sc->vtblk_vq;
again:
VTBLK_LOCK(sc);
if (sc->vtblk_flags & VTBLK_FLAG_DETACH) {
VTBLK_UNLOCK(sc);
@ -872,9 +837,7 @@ vtblk_intr_task(void *arg, int pending)
if (virtqueue_enable_intr(vq) != 0) {
virtqueue_disable_intr(vq);
VTBLK_UNLOCK(sc);
taskqueue_enqueue_fast(sc->vtblk_tq,
&sc->vtblk_intr_task);
return;
goto again;
}
VTBLK_UNLOCK(sc);

View file

@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <sys/random.h>
#include <sys/sglist.h>
#include <sys/lock.h>
@ -97,7 +96,6 @@ static void vtnet_set_hwaddr(struct vtnet_softc *);
static int vtnet_is_link_up(struct vtnet_softc *);
static void vtnet_update_link_status(struct vtnet_softc *);
static void vtnet_watchdog(struct vtnet_softc *);
static void vtnet_config_change_task(void *, int);
static int vtnet_change_mtu(struct vtnet_softc *, int);
static int vtnet_ioctl(struct ifnet *, u_long, caddr_t);
@ -123,8 +121,7 @@ static int vtnet_rx_csum(struct vtnet_softc *, struct mbuf *,
struct virtio_net_hdr *);
static int vtnet_rxeof_merged(struct vtnet_softc *, struct mbuf *, int);
static int vtnet_rxeof(struct vtnet_softc *, int, int *);
static void vtnet_rx_intr_task(void *, int);
static int vtnet_rx_vq_intr(void *);
static void vtnet_rx_vq_intr(void *);
static void vtnet_txeof(struct vtnet_softc *);
static struct mbuf * vtnet_tx_offload(struct vtnet_softc *, struct mbuf *,
@ -135,8 +132,7 @@ static int vtnet_encap(struct vtnet_softc *, struct mbuf **);
static void vtnet_start_locked(struct ifnet *);
static void vtnet_start(struct ifnet *);
static void vtnet_tick(void *);
static void vtnet_tx_intr_task(void *, int);
static int vtnet_tx_vq_intr(void *);
static void vtnet_tx_vq_intr(void *);
static void vtnet_stop(struct vtnet_softc *);
static int vtnet_reinit(struct vtnet_softc *);
@ -427,19 +423,6 @@ vtnet_attach(device_t dev)
ifp->if_capabilities |= IFCAP_POLLING;
#endif
TASK_INIT(&sc->vtnet_rx_intr_task, 0, vtnet_rx_intr_task, sc);
TASK_INIT(&sc->vtnet_tx_intr_task, 0, vtnet_tx_intr_task, sc);
TASK_INIT(&sc->vtnet_cfgchg_task, 0, vtnet_config_change_task, sc);
sc->vtnet_tq = taskqueue_create_fast("vtnet_taskq", M_NOWAIT,
taskqueue_thread_enqueue, &sc->vtnet_tq);
if (sc->vtnet_tq == NULL) {
error = ENOMEM;
device_printf(dev, "cannot allocate taskqueue\n");
ether_ifdetach(ifp);
goto fail;
}
error = virtio_setup_intr(dev, INTR_TYPE_NET);
if (error) {
device_printf(dev, "cannot setup virtqueue interrupts\n");
@ -447,9 +430,6 @@ vtnet_attach(device_t dev)
goto fail;
}
taskqueue_start_threads(&sc->vtnet_tq, 1, PI_NET, "%s taskq",
device_get_nameunit(dev));
/*
* Device defaults to promiscuous mode for backwards
* compatibility. Turn it off if possible.
@ -495,18 +475,10 @@ vtnet_detach(device_t dev)
VTNET_UNLOCK(sc);
callout_drain(&sc->vtnet_tick_ch);
taskqueue_drain(taskqueue_fast, &sc->vtnet_cfgchg_task);
ether_ifdetach(ifp);
}
if (sc->vtnet_tq != NULL) {
taskqueue_drain(sc->vtnet_tq, &sc->vtnet_rx_intr_task);
taskqueue_drain(sc->vtnet_tq, &sc->vtnet_tx_intr_task);
taskqueue_free(sc->vtnet_tq);
sc->vtnet_tq = NULL;
}
if (sc->vtnet_vlan_attach != NULL) {
EVENTHANDLER_DEREGISTER(vlan_config, sc->vtnet_vlan_attach);
sc->vtnet_vlan_attach = NULL;
@ -590,9 +562,11 @@ vtnet_config_change(device_t dev)
sc = device_get_softc(dev);
taskqueue_enqueue_fast(taskqueue_fast, &sc->vtnet_cfgchg_task);
VTNET_LOCK(sc);
vtnet_update_link_status(sc);
VTNET_UNLOCK(sc);
return (1);
return (0);
}
static void
@ -788,18 +762,6 @@ vtnet_watchdog(struct vtnet_softc *sc)
vtnet_init_locked(sc);
}
static void
vtnet_config_change_task(void *arg, int pending)
{
struct vtnet_softc *sc;
sc = arg;
VTNET_LOCK(sc);
vtnet_update_link_status(sc);
VTNET_UNLOCK(sc);
}
static int
vtnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
@ -1705,15 +1667,16 @@ vtnet_rxeof(struct vtnet_softc *sc, int count, int *rx_npktsp)
}
static void
vtnet_rx_intr_task(void *arg, int pending)
vtnet_rx_vq_intr(void *xsc)
{
struct vtnet_softc *sc;
struct ifnet *ifp;
int more;
sc = arg;
sc = xsc;
ifp = sc->vtnet_ifp;
again:
VTNET_LOCK(sc);
#ifdef DEVICE_POLLING
@ -1730,31 +1693,15 @@ vtnet_rx_intr_task(void *arg, int pending)
}
more = vtnet_rxeof(sc, sc->vtnet_rx_process_limit, NULL);
if (!more && vtnet_enable_rx_intr(sc) != 0) {
vtnet_disable_rx_intr(sc);
more = 1;
if (more || vtnet_enable_rx_intr(sc) != 0) {
if (!more)
vtnet_disable_rx_intr(sc);
sc->vtnet_stats.rx_task_rescheduled++;
VTNET_UNLOCK(sc);
goto again;
}
VTNET_UNLOCK(sc);
if (more) {
sc->vtnet_stats.rx_task_rescheduled++;
taskqueue_enqueue_fast(sc->vtnet_tq,
&sc->vtnet_rx_intr_task);
}
}
static int
vtnet_rx_vq_intr(void *xsc)
{
struct vtnet_softc *sc;
sc = xsc;
vtnet_disable_rx_intr(sc);
taskqueue_enqueue_fast(sc->vtnet_tq, &sc->vtnet_rx_intr_task);
return (1);
}
static void
@ -2077,14 +2024,15 @@ vtnet_tick(void *xsc)
}
static void
vtnet_tx_intr_task(void *arg, int pending)
vtnet_tx_vq_intr(void *xsc)
{
struct vtnet_softc *sc;
struct ifnet *ifp;
sc = arg;
sc = xsc;
ifp = sc->vtnet_ifp;
again:
VTNET_LOCK(sc);
#ifdef DEVICE_POLLING
@ -2109,26 +2057,12 @@ vtnet_tx_intr_task(void *arg, int pending)
vtnet_disable_tx_intr(sc);
sc->vtnet_stats.tx_task_rescheduled++;
VTNET_UNLOCK(sc);
taskqueue_enqueue_fast(sc->vtnet_tq, &sc->vtnet_tx_intr_task);
return;
goto again;
}
VTNET_UNLOCK(sc);
}
static int
vtnet_tx_vq_intr(void *xsc)
{
struct vtnet_softc *sc;
sc = xsc;
vtnet_disable_tx_intr(sc);
taskqueue_enqueue_fast(sc->vtnet_tq, &sc->vtnet_tx_intr_task);
return (1);
}
static void
vtnet_stop(struct vtnet_softc *sc)
{

View file

@ -79,11 +79,6 @@ struct vtnet_softc {
int vtnet_watchdog_timer;
uint64_t vtnet_features;
struct taskqueue *vtnet_tq;
struct task vtnet_rx_intr_task;
struct task vtnet_tx_intr_task;
struct task vtnet_cfgchg_task;
struct vtnet_statistics vtnet_stats;
struct callout vtnet_tick_ch;

View file

@ -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_HANDLED : FILTER_STRAY);
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];
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);
}

View file

@ -40,7 +40,6 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/callout.h>
#include <sys/taskqueue.h>
#include <sys/queue.h>
#include <sys/sbuf.h>
@ -172,13 +171,10 @@ static struct vtscsi_request * vtscsi_dequeue_request(struct vtscsi_softc *);
static void vtscsi_complete_request(struct vtscsi_request *);
static void vtscsi_complete_vq(struct vtscsi_softc *, struct virtqueue *);
static void vtscsi_control_vq_task(void *, int);
static void vtscsi_event_vq_task(void *, int);
static void vtscsi_request_vq_task(void *, int);
static int vtscsi_control_vq_intr(void *);
static int vtscsi_event_vq_intr(void *);
static int vtscsi_request_vq_intr(void *);
static void vtscsi_control_vq_intr(void *);
static void vtscsi_event_vq_intr(void *);
static void vtscsi_request_vq_intr(void *);
static void vtscsi_disable_vqs_intr(struct vtscsi_softc *);
static void vtscsi_enable_vqs_intr(struct vtscsi_softc *);
@ -333,30 +329,12 @@ vtscsi_attach(device_t dev)
goto fail;
}
TASK_INIT(&sc->vtscsi_control_intr_task, 0,
vtscsi_control_vq_task, sc);
TASK_INIT(&sc->vtscsi_event_intr_task, 0,
vtscsi_event_vq_task, sc);
TASK_INIT(&sc->vtscsi_request_intr_task, 0,
vtscsi_request_vq_task, sc);
sc->vtscsi_tq = taskqueue_create_fast("vtscsi_taskq", M_NOWAIT,
taskqueue_thread_enqueue, &sc->vtscsi_tq);
if (sc->vtscsi_tq == NULL) {
error = ENOMEM;
device_printf(dev, "cannot allocate taskqueue\n");
goto fail;
}
error = virtio_setup_intr(dev, INTR_TYPE_CAM);
if (error) {
device_printf(dev, "cannot setup virtqueue interrupts\n");
goto fail;
}
taskqueue_start_threads(&sc->vtscsi_tq, 1, PI_DISK, "%s taskq",
device_get_nameunit(dev));
vtscsi_enable_vqs_intr(sc);
/*
@ -389,14 +367,6 @@ vtscsi_detach(device_t dev)
vtscsi_stop(sc);
VTSCSI_UNLOCK(sc);
if (sc->vtscsi_tq != NULL) {
taskqueue_drain(sc->vtscsi_tq, &sc->vtscsi_control_intr_task);
taskqueue_drain(sc->vtscsi_tq, &sc->vtscsi_event_intr_task);
taskqueue_drain(sc->vtscsi_tq, &sc->vtscsi_request_intr_task);
taskqueue_free(sc->vtscsi_tq);
sc->vtscsi_tq = NULL;
}
vtscsi_complete_vqs(sc);
vtscsi_drain_vqs(sc);
@ -2152,14 +2122,15 @@ vtscsi_complete_vq(struct vtscsi_softc *sc, struct virtqueue *vq)
}
static void
vtscsi_control_vq_task(void *arg, int pending)
vtscsi_control_vq_intr(void *xsc)
{
struct vtscsi_softc *sc;
struct virtqueue *vq;
sc = arg;
sc = xsc;
vq = sc->vtscsi_control_vq;
again:
VTSCSI_LOCK(sc);
vtscsi_complete_vq(sc, sc->vtscsi_control_vq);
@ -2167,24 +2138,23 @@ vtscsi_control_vq_task(void *arg, int pending)
if (virtqueue_enable_intr(vq) != 0) {
virtqueue_disable_intr(vq);
VTSCSI_UNLOCK(sc);
taskqueue_enqueue_fast(sc->vtscsi_tq,
&sc->vtscsi_control_intr_task);
return;
goto again;
}
VTSCSI_UNLOCK(sc);
}
static void
vtscsi_event_vq_task(void *arg, int pending)
vtscsi_event_vq_intr(void *xsc)
{
struct vtscsi_softc *sc;
struct virtqueue *vq;
struct virtio_scsi_event *event;
sc = arg;
sc = xsc;
vq = sc->vtscsi_event_vq;
again:
VTSCSI_LOCK(sc);
while ((event = virtqueue_dequeue(vq, NULL)) != NULL)
@ -2193,23 +2163,22 @@ vtscsi_event_vq_task(void *arg, int pending)
if (virtqueue_enable_intr(vq) != 0) {
virtqueue_disable_intr(vq);
VTSCSI_UNLOCK(sc);
taskqueue_enqueue_fast(sc->vtscsi_tq,
&sc->vtscsi_control_intr_task);
return;
goto again;
}
VTSCSI_UNLOCK(sc);
}
static void
vtscsi_request_vq_task(void *arg, int pending)
vtscsi_request_vq_intr(void *xsc)
{
struct vtscsi_softc *sc;
struct virtqueue *vq;
sc = arg;
sc = xsc;
vq = sc->vtscsi_request_vq;
again:
VTSCSI_LOCK(sc);
vtscsi_complete_vq(sc, sc->vtscsi_request_vq);
@ -2217,56 +2186,12 @@ vtscsi_request_vq_task(void *arg, int pending)
if (virtqueue_enable_intr(vq) != 0) {
virtqueue_disable_intr(vq);
VTSCSI_UNLOCK(sc);
taskqueue_enqueue_fast(sc->vtscsi_tq,
&sc->vtscsi_request_intr_task);
return;
goto again;
}
VTSCSI_UNLOCK(sc);
}
static int
vtscsi_control_vq_intr(void *xsc)
{
struct vtscsi_softc *sc;
sc = xsc;
virtqueue_disable_intr(sc->vtscsi_control_vq);
taskqueue_enqueue_fast(sc->vtscsi_tq,
&sc->vtscsi_control_intr_task);
return (1);
}
static int
vtscsi_event_vq_intr(void *xsc)
{
struct vtscsi_softc *sc;
sc = xsc;
virtqueue_disable_intr(sc->vtscsi_event_vq);
taskqueue_enqueue_fast(sc->vtscsi_tq,
&sc->vtscsi_event_intr_task);
return (1);
}
static int
vtscsi_request_vq_intr(void *xsc)
{
struct vtscsi_softc *sc;
sc = xsc;
virtqueue_disable_intr(sc->vtscsi_request_vq);
taskqueue_enqueue_fast(sc->vtscsi_tq,
&sc->vtscsi_request_intr_task);
return (1);
}
static void
vtscsi_disable_vqs_intr(struct vtscsi_softc *sc)
{

View file

@ -62,11 +62,6 @@ struct vtscsi_softc {
struct virtqueue *vtscsi_event_vq;
struct virtqueue *vtscsi_request_vq;
struct taskqueue *vtscsi_tq;
struct task vtscsi_control_intr_task;
struct task vtscsi_event_intr_task;
struct task vtscsi_request_intr_task;
struct cam_sim *vtscsi_sim;
struct cam_path *vtscsi_path;

View file

@ -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);
}
};

View file

@ -414,16 +414,25 @@ virtqueue_nused(struct virtqueue *vq)
}
int
virtqueue_intr_filter(struct virtqueue *vq)
{
if (__predict_false(vq->vq_intrhand == NULL))
return (0);
if (vq->vq_used_cons_idx == vq->vq_ring.used->idx)
return (0);
virtqueue_disable_intr(vq);
return (1);
}
void
virtqueue_intr(struct virtqueue *vq)
{
if (vq->vq_intrhand == NULL ||
vq->vq_used_cons_idx == vq->vq_ring.used->idx)
return (0);
vq->vq_intrhand(vq->vq_intrhand_arg);
return (1);
if (__predict_true(vq->vq_intrhand != NULL))
vq->vq_intrhand(vq->vq_intrhand_arg);
}
int

View file

@ -39,7 +39,7 @@ struct sglist;
#define VIRTIO_RING_F_EVENT_IDX (1 << 29)
/* Device callback for a virtqueue interrupt. */
typedef int virtqueue_intr_t(void *);
typedef void virtqueue_intr_t(void *);
#define VIRTQUEUE_MAX_NAME_SZ 32
@ -70,7 +70,8 @@ void *virtqueue_drain(struct virtqueue *vq, int *last);
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);