Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Feb 2011 18:42:53 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r218198 - in stable/8/sys/dev: ae age alc ale nfe
Message-ID:  <201102021842.p12IgrbJ018217@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Wed Feb  2 18:42:53 2011
New Revision: 218198
URL: http://svn.freebsd.org/changeset/base/218198

Log:
  MFC r216925,217331,217349,217542:
  r216925:
    Add a 'locked' variant of the foo_start() routine and call it directly
    from interrupt handlers and watchdog routines instead of queueing a task
    to call foo_start().
  
  r217331:
    Make sure to invoke unlocked foo_start since the taskqueue does not
    hold a driver lock. This should fix a regression introduced in
    r216925.
  
  r217349:
    Forgot to remove unlock of the driver lock from age_start_locked() when
    converting it to a locked variant.
  
  r217542:
    Fix some bugs in my last set of changes to ale(4):
    - Remove extra unlock from end of ale_start_locked().
    - Expand scope of locking in interrupt handler.
    - Move ether_ifdetach() earlier and retire now-unneeded DETACH flag.
  
    Tested by:	Aryeh Friedman

Modified:
  stable/8/sys/dev/ae/if_ae.c
  stable/8/sys/dev/ae/if_aevar.h
  stable/8/sys/dev/age/if_age.c
  stable/8/sys/dev/age/if_agevar.h
  stable/8/sys/dev/alc/if_alc.c
  stable/8/sys/dev/alc/if_alcvar.h
  stable/8/sys/dev/ale/if_ale.c
  stable/8/sys/dev/ale/if_alevar.h
  stable/8/sys/dev/nfe/if_nfe.c
  stable/8/sys/dev/nfe/if_nfevar.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/ae/if_ae.c
==============================================================================
--- stable/8/sys/dev/ae/if_ae.c	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/ae/if_ae.c	Wed Feb  2 18:42:53 2011	(r218198)
@@ -124,10 +124,10 @@ static int	ae_resume(device_t dev);
 static unsigned int	ae_tx_avail_size(ae_softc_t *sc);
 static int	ae_encap(ae_softc_t *sc, struct mbuf **m_head);
 static void	ae_start(struct ifnet *ifp);
+static void	ae_start_locked(struct ifnet *ifp);
 static void	ae_link_task(void *arg, int pending);
 static void	ae_stop_rxmac(ae_softc_t *sc);
 static void	ae_stop_txmac(ae_softc_t *sc);
-static void	ae_tx_task(void *arg, int pending);
 static void	ae_mac_config(ae_softc_t *sc);
 static int	ae_intr(void *arg);
 static void	ae_int_task(void *arg, int pending);
@@ -402,7 +402,6 @@ ae_attach(device_t dev)
 	/*
 	 * Create and run all helper tasks.
 	 */
-	TASK_INIT(&sc->tx_task, 1, ae_tx_task, ifp);
 	sc->tq = taskqueue_create_fast("ae_taskq", M_WAITOK,
             taskqueue_thread_enqueue, &sc->tq);
 	if (sc->tq == NULL) {
@@ -763,7 +762,6 @@ ae_detach(device_t dev)
 		AE_UNLOCK(sc);
 		callout_drain(&sc->tick_ch);
 		taskqueue_drain(sc->tq, &sc->int_task);
-		taskqueue_drain(sc->tq, &sc->tx_task);
 		taskqueue_drain(taskqueue_swi, &sc->link_task);
 		ether_ifdetach(ifp);
 	}
@@ -1518,23 +1516,32 @@ static void
 ae_start(struct ifnet *ifp)
 {
 	ae_softc_t *sc;
+
+	sc = ifp->if_softc;
+	AE_LOCK(sc);
+	ae_start_locked(ifp);
+	AE_UNLOCK(sc);
+}
+
+static void
+ae_start_locked(struct ifnet *ifp)
+{
+	ae_softc_t *sc;
 	unsigned int count;
 	struct mbuf *m0;
 	int error;
 
 	sc = ifp->if_softc;
 	KASSERT(sc != NULL, ("[ae, %d]: sc is NULL", __LINE__));
-	AE_LOCK(sc);
+	AE_LOCK_ASSERT(sc);
 
 #ifdef AE_DEBUG
 	if_printf(ifp, "Start called.\n");
 #endif
 
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
-	    IFF_DRV_RUNNING || (sc->flags & AE_FLAG_LINK) == 0) {
-		AE_UNLOCK(sc);
+	    IFF_DRV_RUNNING || (sc->flags & AE_FLAG_LINK) == 0)
 		return;
-	}
 
 	count = 0;
 	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
@@ -1570,7 +1577,6 @@ ae_start(struct ifnet *ifp)
 		if_printf(ifp, "Tx pos now is %d.\n", sc->txd_cur);
 #endif
 	}
-	AE_UNLOCK(sc);
 }
 
 static void
@@ -1704,15 +1710,6 @@ ae_stop_txmac(ae_softc_t *sc)
 }
 
 static void
-ae_tx_task(void *arg, int pending)
-{
-	struct ifnet *ifp;
-
-	ifp = (struct ifnet *)arg;
-	ae_start(ifp);
-}
-
-static void
 ae_mac_config(ae_softc_t *sc)
 {
 	struct mii_data *mii;
@@ -1869,7 +1866,7 @@ ae_tx_intr(ae_softc_t *sc)
 	
 	if ((sc->flags & AE_FLAG_TXAVAIL) != 0) {
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			taskqueue_enqueue(sc->tq, &sc->tx_task);
+			ae_start_locked(ifp);
 	}
 
 	/*
@@ -1997,7 +1994,7 @@ ae_watchdog(ae_softc_t *sc)
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	ae_init_locked(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		taskqueue_enqueue(sc->tq, &sc->tx_task);
+		ae_start_locked(ifp);
 }
 
 static void

Modified: stable/8/sys/dev/ae/if_aevar.h
==============================================================================
--- stable/8/sys/dev/ae/if_aevar.h	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/ae/if_aevar.h	Wed Feb  2 18:42:53 2011	(r218198)
@@ -119,7 +119,6 @@ typedef struct ae_softc	{
 
 	/* Tasks. */
 	struct task		int_task;
-	struct task		tx_task;
 	struct task		link_task;
 	struct taskqueue	*tq;
 	

Modified: stable/8/sys/dev/age/if_age.c
==============================================================================
--- stable/8/sys/dev/age/if_age.c	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/age/if_age.c	Wed Feb  2 18:42:53 2011	(r218198)
@@ -118,8 +118,8 @@ static void age_setwol(struct age_softc 
 static int age_suspend(device_t);
 static int age_resume(device_t);
 static int age_encap(struct age_softc *, struct mbuf **);
-static void age_tx_task(void *, int);
 static void age_start(struct ifnet *);
+static void age_start_locked(struct ifnet *);
 static void age_watchdog(struct age_softc *);
 static int age_ioctl(struct ifnet *, u_long, caddr_t);
 static void age_mac_config(struct age_softc *);
@@ -636,7 +636,6 @@ age_attach(device_t dev)
 	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
 
 	/* Create local taskq. */
-	TASK_INIT(&sc->age_tx_task, 1, age_tx_task, ifp);
 	sc->age_tq = taskqueue_create_fast("age_taskq", M_WAITOK,
 	    taskqueue_thread_enqueue, &sc->age_tq);
 	if (sc->age_tq == NULL) {
@@ -693,7 +692,6 @@ age_detach(device_t dev)
 		AGE_UNLOCK(sc);
 		callout_drain(&sc->age_tick_ch);
 		taskqueue_drain(sc->age_tq, &sc->age_int_task);
-		taskqueue_drain(sc->age_tq, &sc->age_tx_task);
 		taskqueue_drain(taskqueue_swi, &sc->age_link_task);
 		ether_ifdetach(ifp);
 	}
@@ -1706,16 +1704,18 @@ age_encap(struct age_softc *sc, struct m
 }
 
 static void
-age_tx_task(void *arg, int pending)
+age_start(struct ifnet *ifp)
 {
-	struct ifnet *ifp;
+        struct age_softc *sc;
 
-	ifp = (struct ifnet *)arg;
-	age_start(ifp);
+	sc = ifp->if_softc;
+	AGE_LOCK(sc);
+	age_start_locked(ifp);
+	AGE_UNLOCK(sc);
 }
 
 static void
-age_start(struct ifnet *ifp)
+age_start_locked(struct ifnet *ifp)
 {
         struct age_softc *sc;
         struct mbuf *m_head;
@@ -1723,13 +1723,11 @@ age_start(struct ifnet *ifp)
 
 	sc = ifp->if_softc;
 
-	AGE_LOCK(sc);
+	AGE_LOCK_ASSERT(sc);
 
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
-	    IFF_DRV_RUNNING || (sc->age_flags & AGE_FLAG_LINK) == 0) {
-		AGE_UNLOCK(sc);
+	    IFF_DRV_RUNNING || (sc->age_flags & AGE_FLAG_LINK) == 0)
 		return;
-	}
 
 	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
@@ -1762,8 +1760,6 @@ age_start(struct ifnet *ifp)
 		/* Set a timeout in case the chip goes out to lunch. */
 		sc->age_watchdog_timer = AGE_TX_TIMEOUT;
 	}
-
-	AGE_UNLOCK(sc);
 }
 
 static void
@@ -1788,7 +1784,7 @@ age_watchdog(struct age_softc *sc)
 		if_printf(sc->age_ifp,
 		    "watchdog timeout (missed Tx interrupts) -- recovering\n");
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			taskqueue_enqueue(sc->age_tq, &sc->age_tx_task);
+			age_start_locked(ifp);
 		return;
 	}
 	if_printf(sc->age_ifp, "watchdog timeout\n");
@@ -1796,7 +1792,7 @@ age_watchdog(struct age_softc *sc)
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	age_init_locked(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		taskqueue_enqueue(sc->age_tq, &sc->age_tx_task);
+		age_start_locked(ifp);
 }
 
 static int
@@ -2172,7 +2168,7 @@ age_int_task(void *arg, int pending)
 			age_init_locked(sc);
 		}
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			taskqueue_enqueue(sc->age_tq, &sc->age_tx_task);
+			age_start_locked(ifp);
 		if ((status & INTR_SMB) != 0)
 			age_stats_update(sc);
 	}

Modified: stable/8/sys/dev/age/if_agevar.h
==============================================================================
--- stable/8/sys/dev/age/if_agevar.h	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/age/if_agevar.h	Wed Feb  2 18:42:53 2011	(r218198)
@@ -222,7 +222,6 @@ struct age_softc {
 	int			age_tpd_cons;
 
 	struct task		age_int_task;
-	struct task		age_tx_task;
 	struct task		age_link_task;
 	struct taskqueue	*age_tq;
 	struct mtx		age_mtx;

Modified: stable/8/sys/dev/alc/if_alc.c
==============================================================================
--- stable/8/sys/dev/alc/if_alc.c	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/alc/if_alc.c	Wed Feb  2 18:42:53 2011	(r218198)
@@ -159,6 +159,7 @@ static void	alc_setlinkspeed(struct alc_
 static void	alc_setwol(struct alc_softc *);
 static int	alc_shutdown(device_t);
 static void	alc_start(struct ifnet *);
+static void	alc_start_locked(struct ifnet *);
 static void	alc_start_queue(struct alc_softc *);
 static void	alc_stats_clear(struct alc_softc *);
 static void	alc_stats_update(struct alc_softc *);
@@ -168,7 +169,6 @@ static void	alc_stop_queue(struct alc_so
 static int	alc_suspend(device_t);
 static void	alc_sysctl_node(struct alc_softc *);
 static void	alc_tick(void *);
-static void	alc_tx_task(void *, int);
 static void	alc_txeof(struct alc_softc *);
 static void	alc_watchdog(struct alc_softc *);
 static int	sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int);
@@ -1002,7 +1002,6 @@ alc_attach(device_t dev)
 	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
 
 	/* Create local taskq. */
-	TASK_INIT(&sc->alc_tx_task, 1, alc_tx_task, ifp);
 	sc->alc_tq = taskqueue_create_fast("alc_taskq", M_WAITOK,
 	    taskqueue_thread_enqueue, &sc->alc_tq);
 	if (sc->alc_tq == NULL) {
@@ -1059,7 +1058,6 @@ alc_detach(device_t dev)
 		ALC_UNLOCK(sc);
 		callout_drain(&sc->alc_tick_ch);
 		taskqueue_drain(sc->alc_tq, &sc->alc_int_task);
-		taskqueue_drain(sc->alc_tq, &sc->alc_tx_task);
 		ether_ifdetach(ifp);
 	}
 
@@ -2237,16 +2235,18 @@ alc_encap(struct alc_softc *sc, struct m
 }
 
 static void
-alc_tx_task(void *arg, int pending)
+alc_start(struct ifnet *ifp)
 {
-	struct ifnet *ifp;
+	struct alc_softc *sc;
 
-	ifp = (struct ifnet *)arg;
-	alc_start(ifp);
+	sc = ifp->if_softc;
+	ALC_LOCK(sc);
+	alc_start_locked(ifp);
+	ALC_UNLOCK(sc);
 }
 
 static void
-alc_start(struct ifnet *ifp)
+alc_start_locked(struct ifnet *ifp)
 {
 	struct alc_softc *sc;
 	struct mbuf *m_head;
@@ -2254,17 +2254,15 @@ alc_start(struct ifnet *ifp)
 
 	sc = ifp->if_softc;
 
-	ALC_LOCK(sc);
+	ALC_LOCK_ASSERT(sc);
 
 	/* Reclaim transmitted frames. */
 	if (sc->alc_cdata.alc_tx_cnt >= ALC_TX_DESC_HIWAT)
 		alc_txeof(sc);
 
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
-	    IFF_DRV_RUNNING || (sc->alc_flags & ALC_FLAG_LINK) == 0) {
-		ALC_UNLOCK(sc);
+	    IFF_DRV_RUNNING || (sc->alc_flags & ALC_FLAG_LINK) == 0)
 		return;
-	}
 
 	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
@@ -2303,8 +2301,6 @@ alc_start(struct ifnet *ifp)
 		/* Set a timeout in case the chip goes out to lunch. */
 		sc->alc_watchdog_timer = ALC_TX_TIMEOUT;
 	}
-
-	ALC_UNLOCK(sc);
 }
 
 static void
@@ -2330,7 +2326,7 @@ alc_watchdog(struct alc_softc *sc)
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	alc_init_locked(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		taskqueue_enqueue(sc->alc_tq, &sc->alc_tx_task);
+		alc_start_locked(ifp);
 }
 
 static int
@@ -2710,7 +2706,7 @@ alc_int_task(void *arg, int pending)
 		}
 		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
 		    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			taskqueue_enqueue(sc->alc_tq, &sc->alc_tx_task);
+			alc_start(ifp);
 	}
 
 	if (more == EAGAIN ||

Modified: stable/8/sys/dev/alc/if_alcvar.h
==============================================================================
--- stable/8/sys/dev/alc/if_alcvar.h	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/alc/if_alcvar.h	Wed Feb  2 18:42:53 2011	(r218198)
@@ -246,7 +246,6 @@ struct alc_softc {
 	int			alc_buf_size;
 
 	struct task		alc_int_task;
-	struct task		alc_tx_task;
 	struct taskqueue	*alc_tq;
 	struct mtx		alc_mtx;
 };

Modified: stable/8/sys/dev/ale/if_ale.c
==============================================================================
--- stable/8/sys/dev/ale/if_ale.c	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/ale/if_ale.c	Wed Feb  2 18:42:53 2011	(r218198)
@@ -136,6 +136,7 @@ static void	ale_setlinkspeed(struct ale_
 static void	ale_setwol(struct ale_softc *);
 static int	ale_shutdown(device_t);
 static void	ale_start(struct ifnet *);
+static void	ale_start_locked(struct ifnet *);
 static void	ale_stats_clear(struct ale_softc *);
 static void	ale_stats_update(struct ale_softc *);
 static void	ale_stop(struct ale_softc *);
@@ -143,7 +144,6 @@ static void	ale_stop_mac(struct ale_soft
 static int	ale_suspend(device_t);
 static void	ale_sysctl_node(struct ale_softc *);
 static void	ale_tick(void *);
-static void	ale_tx_task(void *, int);
 static void	ale_txeof(struct ale_softc *);
 static void	ale_watchdog(struct ale_softc *);
 static int	sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int);
@@ -625,7 +625,6 @@ ale_attach(device_t dev)
 	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
 
 	/* Create local taskq. */
-	TASK_INIT(&sc->ale_tx_task, 1, ale_tx_task, ifp);
 	sc->ale_tq = taskqueue_create_fast("ale_taskq", M_WAITOK,
 	    taskqueue_thread_enqueue, &sc->ale_tq);
 	if (sc->ale_tq == NULL) {
@@ -676,15 +675,13 @@ ale_detach(device_t dev)
 
 	ifp = sc->ale_ifp;
 	if (device_is_attached(dev)) {
+		ether_ifdetach(ifp);
 		ALE_LOCK(sc);
-		sc->ale_flags |= ALE_FLAG_DETACH;
 		ale_stop(sc);
 		ALE_UNLOCK(sc);
 		callout_drain(&sc->ale_tick_ch);
 		taskqueue_drain(sc->ale_tq, &sc->ale_int_task);
-		taskqueue_drain(sc->ale_tq, &sc->ale_tx_task);
 		taskqueue_drain(taskqueue_swi, &sc->ale_link_task);
-		ether_ifdetach(ifp);
 	}
 
 	if (sc->ale_tq != NULL) {
@@ -1845,16 +1842,18 @@ ale_encap(struct ale_softc *sc, struct m
 }
 
 static void
-ale_tx_task(void *arg, int pending)
+ale_start(struct ifnet *ifp)
 {
-	struct ifnet *ifp;
+        struct ale_softc *sc;
 
-	ifp = (struct ifnet *)arg;
-	ale_start(ifp);
+	sc = ifp->if_softc;
+	ALE_LOCK(sc);
+	ale_start_locked(ifp);
+	ALE_UNLOCK(sc);
 }
 
 static void
-ale_start(struct ifnet *ifp)
+ale_start_locked(struct ifnet *ifp)
 {
         struct ale_softc *sc;
         struct mbuf *m_head;
@@ -1862,17 +1861,15 @@ ale_start(struct ifnet *ifp)
 
 	sc = ifp->if_softc;
 
-	ALE_LOCK(sc);
+	ALE_LOCK_ASSERT(sc);
 
 	/* Reclaim transmitted frames. */
 	if (sc->ale_cdata.ale_tx_cnt >= ALE_TX_DESC_HIWAT)
 		ale_txeof(sc);
 
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
-	    IFF_DRV_RUNNING || (sc->ale_flags & ALE_FLAG_LINK) == 0) {
-		ALE_UNLOCK(sc);
+	    IFF_DRV_RUNNING || (sc->ale_flags & ALE_FLAG_LINK) == 0)
 		return;
-	}
 
 	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
@@ -1906,8 +1903,6 @@ ale_start(struct ifnet *ifp)
 		/* Set a timeout in case the chip goes out to lunch. */
 		sc->ale_watchdog_timer = ALE_TX_TIMEOUT;
 	}
-
-	ALE_UNLOCK(sc);
 }
 
 static void
@@ -1933,7 +1928,7 @@ ale_watchdog(struct ale_softc *sc)
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	ale_init_locked(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		taskqueue_enqueue(sc->ale_tq, &sc->ale_tx_task);
+		ale_start_locked(ifp);
 }
 
 static int
@@ -1971,8 +1966,7 @@ ale_ioctl(struct ifnet *ifp, u_long cmd,
 				    & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
 					ale_rxfilter(sc);
 			} else {
-				if ((sc->ale_flags & ALE_FLAG_DETACH) == 0)
-					ale_init_locked(sc);
+				ale_init_locked(sc);
 			}
 		} else {
 			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
@@ -2283,6 +2277,7 @@ ale_int_task(void *arg, int pending)
 	sc = (struct ale_softc *)arg;
 
 	status = CSR_READ_4(sc, ALE_INTR_STATUS);
+	ALE_LOCK(sc);
 	if (sc->ale_morework != 0)
 		status |= INTR_RX_PKT;
 	if ((status & ALE_INTRS) == 0)
@@ -2298,7 +2293,6 @@ ale_int_task(void *arg, int pending)
 		if (more == EAGAIN)
 			sc->ale_morework = 1;
 		else if (more == EIO) {
-			ALE_LOCK(sc);
 			sc->ale_stats.reset_brk_seq++;
 			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			ale_init_locked(sc);
@@ -2313,23 +2307,25 @@ ale_int_task(void *arg, int pending)
 			if ((status & INTR_DMA_WR_TO_RST) != 0)
 				device_printf(sc->ale_dev,
 				    "DMA write error! -- resetting\n");
-			ALE_LOCK(sc);
 			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			ale_init_locked(sc);
 			ALE_UNLOCK(sc);
 			return;
 		}
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			taskqueue_enqueue(sc->ale_tq, &sc->ale_tx_task);
+			ale_start_locked(ifp);
 	}
 
 	if (more == EAGAIN ||
 	    (CSR_READ_4(sc, ALE_INTR_STATUS) & ALE_INTRS) != 0) {
+		ALE_UNLOCK(sc);
 		taskqueue_enqueue(sc->ale_tq, &sc->ale_int_task);
 		return;
 	}
 
 done:
+	ALE_UNLOCK(sc);
+
 	/* Re-enable interrupts. */
 	CSR_WRITE_4(sc, ALE_INTR_STATUS, 0x7FFFFFFF);
 }
@@ -2586,7 +2582,9 @@ ale_rxeof(struct ale_softc *sc, int coun
 		}
 
 		/* Pass it to upper layer. */
+		ALE_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
+		ALE_LOCK(sc);
 
 		ale_rx_update_page(sc, &rx_page, length, &prod);
 	}

Modified: stable/8/sys/dev/ale/if_alevar.h
==============================================================================
--- stable/8/sys/dev/ale/if_alevar.h	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/ale/if_alevar.h	Wed Feb  2 18:42:53 2011	(r218198)
@@ -206,7 +206,6 @@ struct ale_softc {
 #define	ALE_FLAG_RXCSUM_BUG	0x0080
 #define	ALE_FLAG_TXCSUM_BUG	0x0100
 #define	ALE_FLAG_TXCMB_BUG	0x0200
-#define	ALE_FLAG_DETACH		0x4000
 #define	ALE_FLAG_LINK		0x8000
 
 	struct callout		ale_tick_ch;
@@ -222,7 +221,6 @@ struct ale_softc {
 	int			ale_pagesize;
 
 	struct task		ale_int_task;
-	struct task		ale_tx_task;
 	struct task		ale_link_task;
 	struct taskqueue	*ale_tq;
 	struct mtx		ale_mtx;

Modified: stable/8/sys/dev/nfe/if_nfe.c
==============================================================================
--- stable/8/sys/dev/nfe/if_nfe.c	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/nfe/if_nfe.c	Wed Feb  2 18:42:53 2011	(r218198)
@@ -99,8 +99,8 @@ static int  nfe_jrxeof(struct nfe_softc 
 static void nfe_txeof(struct nfe_softc *);
 static int  nfe_encap(struct nfe_softc *, struct mbuf **);
 static void nfe_setmulti(struct nfe_softc *);
-static void nfe_tx_task(void *, int);
 static void nfe_start(struct ifnet *);
+static void nfe_start_locked(struct ifnet *);
 static void nfe_watchdog(struct ifnet *);
 static void nfe_init(void *);
 static void nfe_init_locked(void *);
@@ -553,7 +553,6 @@ nfe_attach(device_t dev)
 		error = ENOSPC;
 		goto fail;
 	}
-	TASK_INIT(&sc->nfe_tx_task, 1, nfe_tx_task, ifp);
 
 	/*
 	 * Allocate Tx and Rx rings.
@@ -678,7 +677,6 @@ nfe_detach(device_t dev)
 		ifp->if_flags &= ~IFF_UP;
 		NFE_UNLOCK(sc);
 		callout_drain(&sc->nfe_stat_ch);
-		taskqueue_drain(taskqueue_fast, &sc->nfe_tx_task);
 		ether_ifdetach(ifp);
 	}
 
@@ -1630,7 +1628,7 @@ nfe_poll(struct ifnet *ifp, enum poll_cm
 		rx_npkts = nfe_rxeof(sc, count, &rx_npkts);
 	nfe_txeof(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		taskqueue_enqueue_fast(sc->nfe_tq, &sc->nfe_tx_task);
+		nfe_start_locked(ifp);
 
 	if (cmd == POLL_AND_CHECK_STATUS) {
 		if ((r = NFE_READ(sc, sc->nfe_irq_status)) == 0) {
@@ -1898,7 +1896,7 @@ nfe_int_task(void *arg, int pending)
 	nfe_txeof(sc);
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		taskqueue_enqueue_fast(sc->nfe_tq, &sc->nfe_tx_task);
+		nfe_start_locked(ifp);
 
 	NFE_UNLOCK(sc);
 
@@ -2594,29 +2592,27 @@ done:
 
 
 static void
-nfe_tx_task(void *arg, int pending)
+nfe_start(struct ifnet *ifp)
 {
-	struct ifnet *ifp;
+	struct nfe_softc *sc = ifp->if_softc;
 
-	ifp = (struct ifnet *)arg;
-	nfe_start(ifp);
+	NFE_LOCK(sc);
+	nfe_start_locked(ifp);
+	NFE_UNLOCK(sc);
 }
 
-
 static void
-nfe_start(struct ifnet *ifp)
+nfe_start_locked(struct ifnet *ifp)
 {
 	struct nfe_softc *sc = ifp->if_softc;
 	struct mbuf *m0;
 	int enq;
 
-	NFE_LOCK(sc);
+	NFE_LOCK_ASSERT(sc);
 
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
-	    IFF_DRV_RUNNING || sc->nfe_link == 0) {
-		NFE_UNLOCK(sc);
+	    IFF_DRV_RUNNING || sc->nfe_link == 0)
 		return;
-	}
 
 	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd);) {
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
@@ -2646,8 +2642,6 @@ nfe_start(struct ifnet *ifp)
 		 */
 		sc->nfe_watchdog_timer = 5;
 	}
-
-	NFE_UNLOCK(sc);
 }
 
 
@@ -2665,7 +2659,7 @@ nfe_watchdog(struct ifnet *ifp)
 		if_printf(ifp, "watchdog timeout (missed Tx interrupts) "
 		    "-- recovering\n");
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			taskqueue_enqueue_fast(sc->nfe_tq, &sc->nfe_tx_task);
+			nfe_start_locked(ifp);
 		return;
 	}
 	/* Check if we've lost start Tx command. */

Modified: stable/8/sys/dev/nfe/if_nfevar.h
==============================================================================
--- stable/8/sys/dev/nfe/if_nfevar.h	Wed Feb  2 17:31:01 2011	(r218197)
+++ stable/8/sys/dev/nfe/if_nfevar.h	Wed Feb  2 18:42:53 2011	(r218198)
@@ -139,7 +139,6 @@ struct nfe_softc {
 	struct nfe_hw_stats	nfe_stats;
 	struct taskqueue	*nfe_tq;
 	struct task		nfe_int_task;
-	struct task		nfe_tx_task;
 	int			nfe_link;
 	int			nfe_suspended;
 	int			nfe_framesize;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102021842.p12IgrbJ018217>