svn commit: r252702 - in head/sys/dev/virtio: . balloon block network pci scsi

Bryan Venteicher bryanv at FreeBSD.org
Thu Jul 4 17:50:14 UTC 2013


Author: bryanv
Date: Thu Jul  4 17:50:11 2013
New Revision: 252702
URL: http://svnweb.freebsd.org/changeset/base/252702

Log:
  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

Modified:
  head/sys/dev/virtio/balloon/virtio_balloon.c
  head/sys/dev/virtio/block/virtio_blk.c
  head/sys/dev/virtio/network/if_vtnet.c
  head/sys/dev/virtio/network/if_vtnetvar.h
  head/sys/dev/virtio/pci/virtio_pci.c
  head/sys/dev/virtio/scsi/virtio_scsi.c
  head/sys/dev/virtio/scsi/virtio_scsivar.h
  head/sys/dev/virtio/virtio_if.m
  head/sys/dev/virtio/virtqueue.c
  head/sys/dev/virtio/virtqueue.h

Modified: head/sys/dev/virtio/balloon/virtio_balloon.c
==============================================================================
--- head/sys/dev/virtio/balloon/virtio_balloon.c	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/balloon/virtio_balloon.c	Thu Jul  4 17:50:11 2013	(r252702)
@@ -90,7 +90,7 @@ static int	vtballoon_config_change(devic
 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 vtball
 	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

Modified: head/sys/dev/virtio/block/virtio_blk.c
==============================================================================
--- head/sys/dev/virtio/block/virtio_blk.c	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/block/virtio_blk.c	Thu Jul  4 17:50:11 2013	(r252702)
@@ -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_
 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
 	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);

Modified: head/sys/dev/virtio/network/if_vtnet.c
==============================================================================
--- head/sys/dev/virtio/network/if_vtnet.c	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/network/if_vtnet.c	Thu Jul  4 17:50:11 2013	(r252702)
@@ -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 vtne
 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_so
 		    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_soft
 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 
 }
 
 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 pendin
 	}
 
 	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 pendin
 		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)
 {

Modified: head/sys/dev/virtio/network/if_vtnetvar.h
==============================================================================
--- head/sys/dev/virtio/network/if_vtnetvar.h	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/network/if_vtnetvar.h	Thu Jul  4 17:50:11 2013	(r252702)
@@ -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;

Modified: head/sys/dev/virtio/pci/virtio_pci.c
==============================================================================
--- head/sys/dev/virtio/pci/virtio_pci.c	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/pci/virtio_pci.c	Thu Jul  4 17:50:11 2013	(r252702)
@@ -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: head/sys/dev/virtio/scsi/virtio_scsi.c
==============================================================================
--- head/sys/dev/virtio/scsi/virtio_scsi.c	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/scsi/virtio_scsi.c	Thu Jul  4 17:50:11 2013	(r252702)
@@ -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_de
 
 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 *
 }
 
 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 pe
 	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 pend
 	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 pe
 	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)
 {

Modified: head/sys/dev/virtio/scsi/virtio_scsivar.h
==============================================================================
--- head/sys/dev/virtio/scsi/virtio_scsivar.h	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/scsi/virtio_scsivar.h	Thu Jul  4 17:50:11 2013	(r252702)
@@ -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;
 

Modified: head/sys/dev/virtio/virtio_if.m
==============================================================================
--- head/sys/dev/virtio/virtio_if.m	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/virtio_if.m	Thu Jul  4 17:50:11 2013	(r252702)
@@ -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: head/sys/dev/virtio/virtqueue.c
==============================================================================
--- head/sys/dev/virtio/virtqueue.c	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/virtqueue.c	Thu Jul  4 17:50:11 2013	(r252702)
@@ -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: head/sys/dev/virtio/virtqueue.h
==============================================================================
--- head/sys/dev/virtio/virtqueue.h	Thu Jul  4 15:21:27 2013	(r252701)
+++ head/sys/dev/virtio/virtqueue.h	Thu Jul  4 17:50:11 2013	(r252702)
@@ -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 *
 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-head mailing list