From owner-p4-projects@FreeBSD.ORG Fri Aug 4 14:43:40 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B058E16A4DE; Fri, 4 Aug 2006 14:43:40 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6B71216A4DA for ; Fri, 4 Aug 2006 14:43:40 +0000 (UTC) (envelope-from piso@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 20D2043D73 for ; Fri, 4 Aug 2006 14:43:34 +0000 (GMT) (envelope-from piso@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k74EhXGl096856 for ; Fri, 4 Aug 2006 14:43:33 GMT (envelope-from piso@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k74EhXDD096852 for perforce@freebsd.org; Fri, 4 Aug 2006 14:43:33 GMT (envelope-from piso@freebsd.org) Date: Fri, 4 Aug 2006 14:43:33 GMT Message-Id: <200608041443.k74EhXDD096852@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to piso@freebsd.org using -f From: Paolo Pisati To: Perforce Change Reviews Cc: Subject: PERFORCE change 103172 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Aug 2006 14:43:41 -0000 http://perforce.freebsd.org/chv.cgi?CH=103172 Change 103172 by piso@piso_newluxor on 2006/08/04 14:43:24 Modify again bfe: this time use a combination of ithread handler (transmission path) and taskqueue (errors and link handling). The advantage of this approach is that we don't have to introduce any mutex to synchronize the filter and the thread/tasks, but on the other hand every driver will grow its own taskqueue+tasks, and it will result in some code duplication. Affected files ... .. //depot/projects/soc2006/intr_filter/dev/bfe/if_bfe.c#5 edit .. //depot/projects/soc2006/intr_filter/dev/bfe/if_bfereg.h#3 edit Differences ... ==== //depot/projects/soc2006/intr_filter/dev/bfe/if_bfe.c#5 (text+ko) ==== @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -93,6 +94,8 @@ #endif static int bfe_filter (void *); static void bfe_handler (void *); +static void bfe_errors (void *, int); +static void bfe_stops (void *, int); static void bfe_start (struct ifnet *); static void bfe_start_locked (struct ifnet *); static int bfe_ioctl (struct ifnet *, u_long, caddr_t); @@ -419,6 +422,14 @@ ifp->if_capabilities |= IFCAP_VLAN_MTU; ifp->if_capenable |= IFCAP_VLAN_MTU; + sc->sc_tq = taskqueue_create("bfe_taskq", M_NOWAIT, + taskqueue_thread_enqueue, &sc->sc_tq); + taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, + "%s taskq", ifp->if_xname); + + TASK_INIT(&sc->sc_errorstask, 0, bfe_errors, sc); + TASK_INIT(&sc->sc_stoptask, 0, bfe_stops, sc); + /* * Hook interrupt last to avoid having to lock softc */ @@ -464,6 +475,9 @@ device_delete_child(dev, sc->bfe_miibus); bfe_release_resources(sc); + taskqueue_drain(sc->sc_tq, &sc->sc_stoptask); + taskqueue_drain(sc->sc_tq, &sc->sc_errorstask); + taskqueue_free(sc->sc_tq); BFE_UNLOCK(sc); mtx_destroy(&sc->bfe_mtx); @@ -1194,9 +1208,10 @@ bfe_filter(void *xsc) { struct bfe_softc *sc = xsc; - u_int32_t imask; + struct ifnet *ifp; + u_int32_t imask, istat, flag; - sc->bfe_istat = CSR_READ_4(sc, BFE_ISTAT); + istat = CSR_READ_4(sc, BFE_ISTAT); imask = CSR_READ_4(sc, BFE_IMASK); /* @@ -1204,49 +1219,28 @@ * chips interrupt mask register to 0 doesn't actually stop the * interrupts */ - sc->bfe_istat &= imask; - CSR_WRITE_4(sc, BFE_ISTAT, sc->bfe_istat); + istat &= imask; + CSR_WRITE_4(sc, BFE_ISTAT, istat); CSR_READ_4(sc, BFE_ISTAT); /* not expecting this interrupt, disregard it */ - if(sc->bfe_istat == 0) + if(istat == 0) return (FILTER_STRAY); - /* disable interrupts - not that it actually does..*/ - CSR_WRITE_4(sc, BFE_IMASK, 0); - CSR_READ_4(sc, BFE_IMASK); - - return (FILTER_HANDLED | FILTER_SCHEDULE_THREAD); -} - -static void -bfe_handler(void *xsc) -{ - struct bfe_softc *sc = xsc; - struct ifnet *ifp; - u_int32_t istat, flag; - - ifp = sc->bfe_ifp; - - BFE_LOCK(sc); - - istat = sc->bfe_istat; if(istat & BFE_ISTAT_ERRORS) { - if (istat & BFE_ISTAT_DSCE) { printf("if_bfe Descriptor Error\n"); - bfe_stop(sc); - BFE_UNLOCK(sc); - return; + taskqueue_enqueue(sc->sc_tq, &sc->sc_stoptask); + return (FILTER_HANDLED); } if (istat & BFE_ISTAT_DPE) { printf("if_bfe Descriptor Protocol Error\n"); - bfe_stop(sc); - BFE_UNLOCK(sc); - return; + taskqueue_enqueue(sc->sc_tq, &sc->sc_stoptask); + return (FILTER_HANDLED); } + ifp = sc->bfe_ifp; flag = CSR_READ_4(sc, BFE_DMATX_STAT); if(flag & BFE_STAT_EMASK) ifp->if_oerrors++; @@ -1254,28 +1248,61 @@ flag = CSR_READ_4(sc, BFE_DMARX_STAT); if(flag & BFE_RX_FLAG_ERRORS) ifp->if_ierrors++; + + taskqueue_enqueue(sc->sc_tq, &sc->sc_errorstask); + return (FILTER_HANDLED); + } + + /* disable interrupts - not that it actually does..*/ + CSR_WRITE_4(sc, BFE_IMASK, 0); + CSR_READ_4(sc, BFE_IMASK); + + return (FILTER_HANDLED | FILTER_SCHEDULE_THREAD); +} + +static void +bfe_stops(void *context, int p __unused) { + struct bfe_softc *sc = context; + + BFE_LOCK(sc); + bfe_stop(sc); + BFE_UNLOCK(sc); +} + +static void +bfe_errors(void *context, int p __unused) { + struct bfe_softc *sc = context; + struct ifnet *ifp; + + BFE_LOCK(sc); + ifp = sc->bfe_ifp; + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + bfe_init_locked(sc); + BFE_UNLOCK(sc); +} + +static void +bfe_handler(void *xsc) { + struct bfe_softc *sc = xsc; + struct ifnet *ifp; - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - bfe_init_locked(sc); - } + BFE_LOCK(sc); + ifp = sc->bfe_ifp; - /* A packet was received */ - if(istat & BFE_ISTAT_RX) - bfe_rxeof(sc); + /* A packet was received */ + bfe_rxeof(sc); /* A packet was sent */ - if(istat & BFE_ISTAT_TX) - bfe_txeof(sc); + bfe_txeof(sc); /* We have packets pending, fire them out */ if (ifp->if_drv_flags & IFF_DRV_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) bfe_start_locked(ifp); - BFE_UNLOCK(sc); - /* Enable interrupts */ CSR_WRITE_4(sc, BFE_IMASK, BFE_IMASK_DEF); + BFE_UNLOCK(sc); } #if 0 ==== //depot/projects/soc2006/intr_filter/dev/bfe/if_bfereg.h#3 (text+ko) ==== @@ -510,7 +510,9 @@ struct bfe_data bfe_tx_ring[BFE_TX_LIST_CNT]; /* XXX */ struct bfe_data bfe_rx_ring[BFE_RX_LIST_CNT]; /* XXX */ struct mtx bfe_mtx; - u_int32_t bfe_istat; + struct taskqueue *sc_tq; /* private task queue */ + struct task sc_stoptask; + struct task sc_errorstask; u_int32_t bfe_flags; u_int32_t bfe_imask; u_int32_t bfe_dma_offset;