Date: Mon, 6 Oct 2003 13:58:29 -0700 (PDT) From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 39273 for review Message-ID: <200310062058.h96KwTi0066764@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=39273 Change 39273 by sam@sam_ebb on 2003/10/06 13:58:23 add simple locking Affected files ... .. //depot/projects/netperf/sys/dev/bge/if_bge.c#10 edit .. //depot/projects/netperf/sys/dev/bge/if_bgereg.h#5 edit Differences ... ==== //depot/projects/netperf/sys/dev/bge/if_bge.c#10 (text+ko) ==== @@ -184,6 +184,7 @@ static void bge_txeof (struct bge_softc *); static void bge_rxeof (struct bge_softc *); +static void bge_tick_locked (struct bge_softc *); static void bge_tick (void *); static void bge_stats_update (struct bge_softc *); static void bge_stats_update_regs @@ -192,8 +193,10 @@ u_int32_t *); static void bge_intr (void *); +static void bge_start_locked (struct ifnet *); static void bge_start (struct ifnet *); static int bge_ioctl (struct ifnet *, u_long, caddr_t); +static void bge_init_locked (struct bge_softc *); static void bge_init (void *); static void bge_stop (struct bge_softc *); static void bge_watchdog (struct ifnet *); @@ -1154,6 +1157,8 @@ u_int32_t hashes[4] = { 0, 0, 0, 0 }; int h, i; + BGE_LOCK_ASSERT(sc); + ifp = &sc->arpcom.ac_if; if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { @@ -2225,15 +2230,12 @@ bge_attach(dev) device_t dev; { - int s; struct ifnet *ifp; struct bge_softc *sc; u_int32_t hwcfg = 0; u_int32_t mac_addr = 0; int unit, error = 0, rid; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); sc->bge_dev = dev; @@ -2270,16 +2272,9 @@ goto fail; } - error = bus_setup_intr(dev, sc->bge_irq, INTR_TYPE_NET, - bge_intr, sc, &sc->bge_intrhand); + sc->bge_unit = unit; - if (error) { - bge_release_resources(sc); - printf("bge%d: couldn't set up irq\n", unit); - goto fail; - } - - sc->bge_unit = unit; + BGE_LOCK_INIT(sc, device_get_nameunit(dev)); /* Try to reset the chip. */ bge_reset(sc); @@ -2449,11 +2444,20 @@ * Call MI attach routine. */ ether_ifattach(ifp, sc->arpcom.ac_enaddr); - callout_handle_init(&sc->bge_stat_ch); + callout_init(&sc->bge_stat_ch, CALLOUT_MPSAFE); + + /* + * Hookup IRQ last. + */ + error = bus_setup_intr(dev, sc->bge_irq, INTR_TYPE_NET | INTR_MPSAFE, + bge_intr, sc, &sc->bge_intrhand); + + if (error) { + bge_release_resources(sc); + printf("bge%d: couldn't set up irq\n", unit); + } fail: - splx(s); - return(error); } @@ -2463,16 +2467,16 @@ { struct bge_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); ifp = &sc->arpcom.ac_if; - ether_ifdetach(ifp); + BGE_LOCK(sc); bge_stop(sc); bge_reset(sc); + BGE_UNLOCK(sc); + + ether_ifdetach(ifp); if (sc->bge_tbi) { ifmedia_removeall(&sc->bge_ifmedia); @@ -2485,8 +2489,6 @@ if (sc->bge_asicrev != BGE_ASICREV_BCM5705) bge_free_jumbo_mem(sc); - splx(s); - return(0); } @@ -2516,6 +2518,9 @@ bge_dma_free(sc); + if (mtx_initialized(&sc->bge_mtx)) /* XXX */ + BGE_LOCK_DESTROY(sc); + return; } @@ -2620,6 +2625,8 @@ struct ifnet *ifp; int stdcnt = 0, jumbocnt = 0; + BGE_LOCK_ASSERT(sc); + ifp = &sc->arpcom.ac_if; bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag, @@ -2732,7 +2739,9 @@ if (have_tag) VLAN_INPUT_TAG(ifp, m, vlan_tag, continue); + BGE_UNLOCK(sc); (*ifp->if_input)(ifp, m); + BGE_LOCK(sc); } bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag, @@ -2762,6 +2771,8 @@ struct bge_tx_bd *cur_tx = NULL; struct ifnet *ifp; + BGE_LOCK_ASSERT(sc); + ifp = &sc->arpcom.ac_if; /* @@ -2805,6 +2816,8 @@ sc = xsc; ifp = &sc->arpcom.ac_if; + BGE_LOCK(sc); + bus_dmamap_sync(sc->bge_cdata.bge_status_tag, sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTWRITE); @@ -2837,8 +2850,8 @@ status = CSR_READ_4(sc, BGE_MAC_STS); if (status & BGE_MACSTAT_MI_INTERRUPT) { sc->bge_link = 0; - untimeout(bge_tick, sc, sc->bge_stat_ch); - bge_tick(sc); + callout_stop(&sc->bge_stat_ch); + bge_tick_locked(sc); /* Clear the interrupt */ CSR_WRITE_4(sc, BGE_MAC_EVT_ENB, BGE_EVTENB_MI_INTERRUPT); @@ -2864,8 +2877,8 @@ if (!(status & (BGE_MACSTAT_PORT_DECODE_ERROR| BGE_MACSTAT_MI_COMPLETE))) { sc->bge_link = 0; - untimeout(bge_tick, sc, sc->bge_stat_ch); - bge_tick(sc); + callout_stop(&sc->bge_stat_ch); + bge_tick_locked(sc); } /* Clear the interrupt */ CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED| @@ -2894,35 +2907,32 @@ CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0); if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) - bge_start(ifp); + bge_start_locked(ifp); + + BGE_UNLOCK(sc); return; } static void -bge_tick(xsc) - void *xsc; +bge_tick_locked(sc) + struct bge_softc *sc; { - struct bge_softc *sc; struct mii_data *mii = NULL; struct ifmedia *ifm = NULL; struct ifnet *ifp; - int s; - sc = xsc; ifp = &sc->arpcom.ac_if; - s = splimp(); + BGE_LOCK_ASSERT(sc); if (sc->bge_asicrev == BGE_ASICREV_BCM5705) bge_stats_update_regs(sc); else bge_stats_update(sc); - sc->bge_stat_ch = timeout(bge_tick, sc, hz); - if (sc->bge_link) { - splx(s); + callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc); + if (sc->bge_link) return; - } if (sc->bge_tbi) { ifm = &sc->bge_ifmedia; @@ -2932,9 +2942,8 @@ CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF); printf("bge%d: gigabit link up\n", sc->bge_unit); if (ifp->if_snd.ifq_head != NULL) - bge_start(ifp); + bge_start_locked(ifp); } - splx(s); return; } @@ -2949,12 +2958,23 @@ printf("bge%d: gigabit link up\n", sc->bge_unit); if (ifp->if_snd.ifq_head != NULL) - bge_start(ifp); + bge_start_locked(ifp); } - splx(s); + return; +} + +static void +bge_tick(xsc) + void *xsc; +{ + struct bge_softc *sc; + + sc = xsc; - return; + BGE_LOCK(sc); + bge_tick_locked(sc); + BGE_UNLOCK(sc); } static void @@ -3093,7 +3113,7 @@ * to the mbuf data regions directly in the transmit descriptors. */ static void -bge_start(ifp) +bge_start_locked(ifp) struct ifnet *ifp; { struct bge_softc *sc; @@ -3162,23 +3182,35 @@ return; } +/* + * Main transmit routine. To avoid having to do mbuf copies, we put pointers + * to the mbuf data regions directly in the transmit descriptors. + */ static void -bge_init(xsc) - void *xsc; +bge_start(ifp) + struct ifnet *ifp; +{ + struct bge_softc *sc; + + sc = ifp->if_softc; + BGE_LOCK(sc); + bge_start_locked(ifp); + BGE_UNLOCK(sc); +} + +static void +bge_init_locked(sc) + struct bge_softc *sc; { - struct bge_softc *sc = xsc; struct ifnet *ifp; u_int16_t *m; - int s; - s = splimp(); + BGE_LOCK_ASSERT(sc); ifp = &sc->arpcom.ac_if; - if (ifp->if_flags & IFF_RUNNING) { - splx(s); + if (ifp->if_flags & IFF_RUNNING) return; - } /* Cancel pending I/O and flush buffers. */ bge_stop(sc); @@ -3191,7 +3223,6 @@ */ if (bge_blockinit(sc)) { printf("bge%d: initialization failure\n", sc->bge_unit); - splx(s); return; } @@ -3266,9 +3297,20 @@ ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - splx(s); + callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc); + + return; +} + +static void +bge_init(xsc) + void *xsc; +{ + struct bge_softc *sc = xsc; - sc->bge_stat_ch = timeout(bge_tick, sc, hz); + BGE_LOCK(sc); + bge_init_locked(sc); + BGE_UNLOCK(sc); return; } @@ -3365,11 +3407,9 @@ { struct bge_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; - int s, mask, error = 0; + int mask, error = 0; struct mii_data *mii; - s = splimp(); - switch(command) { case SIOCSIFMTU: /* Disallow jumbo frames on 5705. */ @@ -3383,6 +3423,7 @@ } break; case SIOCSIFFLAGS: + BGE_LOCK(sc); if (ifp->if_flags & IFF_UP) { /* * If only the state of the PROMISC flag changed, @@ -3403,19 +3444,22 @@ BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC); } else - bge_init(sc); + bge_init_locked(sc); } else { if (ifp->if_flags & IFF_RUNNING) { bge_stop(sc); } } sc->bge_if_flags = ifp->if_flags; + BGE_UNLOCK(sc); error = 0; break; case SIOCADDMULTI: case SIOCDELMULTI: if (ifp->if_flags & IFF_RUNNING) { + BGE_LOCK(sc); bge_setmulti(sc); + BGE_UNLOCK(sc); error = 0; } break; @@ -3445,8 +3489,6 @@ break; } - (void)splx(s); - return(error); } @@ -3481,12 +3523,14 @@ struct mii_data *mii = NULL; int mtmp, itmp; + BGE_LOCK_ASSERT(sc); + ifp = &sc->arpcom.ac_if; if (!sc->bge_tbi) mii = device_get_softc(sc->bge_miibus); - untimeout(bge_tick, sc, sc->bge_stat_ch); + callout_stop(&sc->bge_stat_ch); /* * Disable all of the receiver blocks @@ -3583,8 +3627,10 @@ sc = device_get_softc(dev); + BGE_LOCK(sc); bge_stop(sc); bge_reset(sc); + BGE_UNLOCK(sc); return; } ==== //depot/projects/netperf/sys/dev/bge/if_bgereg.h#5 (text+ko) ==== @@ -2258,6 +2258,7 @@ struct bge_softc { struct arpcom arpcom; /* interface info */ device_t bge_dev; + struct mtx bge_mtx; device_t bge_miibus; bus_space_handle_t bge_bhandle; vm_offset_t bge_vhandle; @@ -2293,7 +2294,14 @@ int bge_if_flags; int bge_txcnt; int bge_link; - struct callout_handle bge_stat_ch; + struct callout bge_stat_ch; char *bge_vpd_prodname; char *bge_vpd_readonly; }; + +#define BGE_LOCK_INIT(_sc, _name) \ + mtx_init(&(_sc)->bge_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) +#define BGE_LOCK(_sc) mtx_lock(&(_sc)->bge_mtx) +#define BGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->bge_mtx, MA_OWNED) +#define BGE_UNLOCK(_sc) mtx_unlock(&(_sc)->bge_mtx) +#define BGE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->bge_mtx)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310062058.h96KwTi0066764>