diff options
-rw-r--r-- | sys/dev/virtio/balloon/virtio_balloon.c | 6 | ||||
-rw-r--r-- | sys/dev/virtio/block/virtio_blk.c | 47 | ||||
-rw-r--r-- | sys/dev/virtio/network/if_vtnet.c | 104 | ||||
-rw-r--r-- | sys/dev/virtio/network/if_vtnetvar.h | 5 | ||||
-rw-r--r-- | sys/dev/virtio/pci/virtio_pci.c | 88 | ||||
-rw-r--r-- | sys/dev/virtio/scsi/virtio_scsi.c | 105 | ||||
-rw-r--r-- | sys/dev/virtio/scsi/virtio_scsivar.h | 5 | ||||
-rw-r--r-- | sys/dev/virtio/virtio_if.m | 3 | ||||
-rw-r--r-- | sys/dev/virtio/virtqueue.c | 17 | ||||
-rw-r--r-- | sys/dev/virtio/virtqueue.h | 5 |
10 files changed, 110 insertions, 275 deletions
diff --git a/sys/dev/virtio/balloon/virtio_balloon.c b/sys/dev/virtio/balloon/virtio_balloon.c index 9b45459..224a651 100644 --- a/sys/dev/virtio/balloon/virtio_balloon.c +++ b/sys/dev/virtio/balloon/virtio_balloon.c @@ -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 diff --git a/sys/dev/virtio/block/virtio_blk.c b/sys/dev/virtio/block/virtio_blk.c index 21d7703..e5f38c41 100644 --- a/sys/dev/virtio/block/virtio_blk.c +++ b/sys/dev/virtio/block/virtio_blk.c @@ -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); diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index 8e2de46..29ed747 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -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; - } - - VTNET_UNLOCK(sc); - - if (more) { + if (more || vtnet_enable_rx_intr(sc) != 0) { + if (!more) + vtnet_disable_rx_intr(sc); sc->vtnet_stats.rx_task_rescheduled++; - taskqueue_enqueue_fast(sc->vtnet_tq, - &sc->vtnet_rx_intr_task); + VTNET_UNLOCK(sc); + goto again; } -} - -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); + VTNET_UNLOCK(sc); } 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) { diff --git a/sys/dev/virtio/network/if_vtnetvar.h b/sys/dev/virtio/network/if_vtnetvar.h index 184870e..da7e61d 100644 --- a/sys/dev/virtio/network/if_vtnetvar.h +++ b/sys/dev/virtio/network/if_vtnetvar.h @@ -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; 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); } diff --git a/sys/dev/virtio/scsi/virtio_scsi.c b/sys/dev/virtio/scsi/virtio_scsi.c index 52f1581..d471937 100644 --- a/sys/dev/virtio/scsi/virtio_scsi.c +++ b/sys/dev/virtio/scsi/virtio_scsi.c @@ -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) { diff --git a/sys/dev/virtio/scsi/virtio_scsivar.h b/sys/dev/virtio/scsi/virtio_scsivar.h index 7afe32f..ca53f21 100644 --- a/sys/dev/virtio/scsi/virtio_scsivar.h +++ b/sys/dev/virtio/scsi/virtio_scsivar.h @@ -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; diff --git a/sys/dev/virtio/virtio_if.m b/sys/dev/virtio/virtio_if.m index 701678c..13b0660 100644 --- a/sys/dev/virtio/virtio_if.m +++ b/sys/dev/virtio/virtio_if.m @@ -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); } }; diff --git a/sys/dev/virtio/virtqueue.c b/sys/dev/virtio/virtqueue.c index 1553afa..275a92d 100644 --- a/sys/dev/virtio/virtqueue.c +++ b/sys/dev/virtio/virtqueue.c @@ -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) { diff --git a/sys/dev/virtio/virtqueue.h b/sys/dev/virtio/virtqueue.h index 0296b8c..80e52ff 100644 --- a/sys/dev/virtio/virtqueue.h +++ b/sys/dev/virtio/virtqueue.h @@ -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); |