diff options
author | bryanv <bryanv@FreeBSD.org> | 2013-07-04 17:50:11 +0000 |
---|---|---|
committer | bryanv <bryanv@FreeBSD.org> | 2013-07-04 17:50:11 +0000 |
commit | ecdd9ae0054b1b8b776661b78e8a20fb0973775d (patch) | |
tree | adfa592c287e8e552c48a18adac66fc0d37fffd6 /sys/dev/virtio/network | |
parent | be7c32fd304a8aa87a4cd877782d254092d1282f (diff) | |
download | FreeBSD-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/network')
-rw-r--r-- | sys/dev/virtio/network/if_vtnet.c | 104 | ||||
-rw-r--r-- | sys/dev/virtio/network/if_vtnetvar.h | 5 |
2 files changed, 19 insertions, 90 deletions
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; |