Date: Sat, 5 Aug 2006 18:06:19 GMT From: Paolo Pisati <piso@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 103263 for review Message-ID: <200608051806.k75I6J1p028816@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=103263 Change 103263 by piso@piso_newluxor on 2006/08/05 18:06:14 Convert xl to use a filter+ithread handler. Unfortunately, under heavy load (trying to transfer a big file from 2 boxes in a LAN) i get many 'watchdog timeout' errors: i'll try to fix it later. Affected files ... .. //depot/projects/soc2006/intr_filter/pci/if_xl.c#3 edit .. //depot/projects/soc2006/intr_filter/pci/if_xlreg.h#2 edit Differences ... ==== //depot/projects/soc2006/intr_filter/pci/if_xl.c#3 (text+ko) ==== @@ -233,11 +233,15 @@ static int xl_encap(struct xl_softc *, struct xl_chain *, struct mbuf *); static void xl_rxeof(struct xl_softc *); static void xl_rxeof_task(void *, int); -static int xl_rx_resync(struct xl_softc *); +__unused static int xl_rx_resync(struct xl_softc *); static void xl_txeof(struct xl_softc *); static void xl_txeof_90xB(struct xl_softc *); static void xl_txeoc(struct xl_softc *); static void xl_intr(void *); +static int xl_filter(void *); +static void xl_stat_tx_complete(void *, int); +static void xl_stat_adfail(void *, int); +static void xl_stat_statsoflow(void *, int); static void xl_start(struct ifnet *); static void xl_start_locked(struct ifnet *); static void xl_start_90xB_locked(struct ifnet *); @@ -1600,13 +1604,21 @@ CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS); } + sc->xl_tq = taskqueue_create("xl_taskq", M_NOWAIT, + taskqueue_thread_enqueue, &sc->xl_tq); + taskqueue_start_threads(&sc->xl_tq, 1, + PI_NET, "%s taskq", ifp->if_xname); + TASK_INIT(&sc->xl_stat_tx_complete, 0, xl_stat_tx_complete, sc); + TASK_INIT(&sc->xl_stat_adfail, 0, xl_stat_adfail, sc); + TASK_INIT(&sc->xl_stat_statsoflow, 0, xl_stat_statsoflow, sc); + /* * Call MI attach routine. */ ether_ifattach(ifp, eaddr); error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET | INTR_MPSAFE, - NULL, xl_intr, sc, &sc->xl_intrhand); + xl_filter, xl_intr, sc, &sc->xl_intrhand); if (error) { device_printf(dev, "couldn't set up irq\n"); ether_ifdetach(ifp); @@ -1715,6 +1727,7 @@ callout_drain(&sc->xl_stat_callout); ether_ifdetach(ifp); } + taskqueue_free(sc->xl_tq); if (sc->xl_miibus) device_delete_child(dev, sc->xl_miibus); bus_generic_detach(dev); @@ -1751,7 +1764,6 @@ sc->xl_ldata.xl_tx_dmamap); bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag); } - mtx_destroy(&sc->xl_mtx); return (0); @@ -1925,7 +1937,7 @@ return (0); } -static int +__unused static int xl_rx_resync(struct xl_softc *sc) { struct xl_chain_onefrag *pos; @@ -2274,68 +2286,94 @@ } static void -xl_intr(void *arg) +xl_stat_tx_complete(void *_sc, int p __unused) { + struct xl_softc *sc = _sc; + struct ifnet *ifp = sc->xl_ifp; + + XL_LOCK(sc); + ifp->if_oerrors++; + xl_txeoc(sc); + XL_UNLOCK(sc); +} + +static void +xl_stat_adfail(void *_sc, int p __unused) { + struct xl_softc *sc = _sc; + + XL_LOCK(sc); + xl_reset(sc); + xl_init_locked(sc); + XL_UNLOCK(sc); +} + +static void +xl_stat_statsoflow(void *_sc, int p __unused) { + struct xl_softc *sc = _sc; + + XL_LOCK(sc); + sc->xl_stats_no_timeout = 1; + xl_stats_update_locked(sc); + sc->xl_stats_no_timeout = 0; + XL_UNLOCK(sc); +} + +static int +xl_filter(void *arg) { struct xl_softc *sc = arg; - struct ifnet *ifp = sc->xl_ifp; u_int16_t status; + int ret = FILTER_HANDLED; + + status = CSR_READ_2(sc, XL_STATUS); + status &= XL_INTRS; - XL_LOCK(sc); + if (status == 0xFFFF) + return (FILTER_STRAY); -#ifdef DEVICE_POLLING - if (ifp->if_capenable & IFCAP_POLLING) { - XL_UNLOCK(sc); - return; - } -#endif + CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|(status & XL_INTRS)); + + if (status & XL_STAT_UP_COMPLETE) + ret |= FILTER_SCHEDULE_THREAD; - while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS && - status != 0xFFFF) { - CSR_WRITE_2(sc, XL_COMMAND, - XL_CMD_INTR_ACK|(status & XL_INTRS)); + if (status & XL_STAT_DOWN_COMPLETE) + ret |= FILTER_SCHEDULE_THREAD; - if (status & XL_STAT_UP_COMPLETE) { - int curpkts; + if (status & XL_STAT_TX_COMPLETE) + taskqueue_enqueue(sc->xl_tq, &sc->xl_stat_tx_complete); - curpkts = ifp->if_ipackets; - xl_rxeof(sc); - if (curpkts == ifp->if_ipackets) { - while (xl_rx_resync(sc)) - xl_rxeof(sc); - } - } + if (status & XL_STAT_ADFAIL) + taskqueue_enqueue(sc->xl_tq, &sc->xl_stat_adfail); - if (status & XL_STAT_DOWN_COMPLETE) { - if (sc->xl_type == XL_TYPE_905B) - xl_txeof_90xB(sc); - else - xl_txeof(sc); - } + if (status & XL_STAT_STATSOFLOW) + taskqueue_enqueue(sc->xl_tq, &sc->xl_stat_statsoflow); - if (status & XL_STAT_TX_COMPLETE) { - ifp->if_oerrors++; - xl_txeoc(sc); - } + /* Disable interrupts */ + CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0); - if (status & XL_STAT_ADFAIL) { - xl_reset(sc); - xl_init_locked(sc); - } + return (ret); +} - if (status & XL_STAT_STATSOFLOW) { - sc->xl_stats_no_timeout = 1; - xl_stats_update_locked(sc); - sc->xl_stats_no_timeout = 0; - } - } +static void +xl_intr(void *arg) { + struct xl_softc *sc = arg; + struct ifnet *ifp = sc->xl_ifp; + XL_LOCK(sc); + xl_rxeof(sc); + if (sc->xl_type == XL_TYPE_905B) + xl_txeof_90xB(sc); + else + xl_txeof(sc); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { if (sc->xl_type == XL_TYPE_905B) xl_start_90xB_locked(ifp); else xl_start_locked(ifp); } - + /* Enable interrupts */ + CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF); + CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS); XL_UNLOCK(sc); } ==== //depot/projects/soc2006/intr_filter/pci/if_xlreg.h#2 (text+ko) ==== @@ -608,6 +608,10 @@ bus_space_tag_t xl_ftag; struct mtx xl_mtx; struct task xl_task; + struct taskqueue *xl_tq; + struct task xl_stat_tx_complete; + struct task xl_stat_adfail; + struct task xl_stat_statsoflow; #ifdef DEVICE_POLLING int rxcycles; #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608051806.k75I6J1p028816>