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>