diff options
author | Christian Weisgerber <naddy@cvs.openbsd.org> | 2009-06-19 14:13:42 +0000 |
---|---|---|
committer | Christian Weisgerber <naddy@cvs.openbsd.org> | 2009-06-19 14:13:42 +0000 |
commit | 06ef5388c14d8728459626b5c0bcd89b3c974ffc (patch) | |
tree | 3d3d1f7508a4a1937f84ab11de957552829a6506 | |
parent | 0268479ba061b5a84e1ec0682cf911c928b1dd62 (diff) |
Tidy up allocation of transmit DMA maps and generalize it to also
tidy up allocation of receive DMA maps. Previously the driver was
using DMA maps off the free list without fully allocating them, in
order to save two or three lines releasing them on error paths.
This was causing it to reuse a map already in use when under load.
From NetBSD.
Revert a workaround against a NULL pointer dereference on alpha
when invoking bus_dmaamp_sync.
All submitted by Brad.
-rw-r--r-- | sys/dev/pci/if_de.c | 88 | ||||
-rw-r--r-- | sys/dev/pci/if_devar.h | 10 |
2 files changed, 61 insertions, 37 deletions
diff --git a/sys/dev/pci/if_de.c b/sys/dev/pci/if_de.c index 13c35da05f9..c2357261601 100644 --- a/sys/dev/pci/if_de.c +++ b/sys/dev/pci/if_de.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_de.c,v 1.101 2008/11/28 02:44:17 brad Exp $ */ +/* $OpenBSD: if_de.c,v 1.102 2009/06/19 14:13:41 naddy Exp $ */ /* $NetBSD: if_de.c,v 1.58 1998/01/12 09:39:58 thorpej Exp $ */ /*- @@ -227,6 +227,10 @@ void tulip_initring(tulip_softc_t * const sc, tulip_ringinfo_t * const ri, tulip_desc_t *descs, int ndescs); void tulip_shutdown(void *arg); +bus_dmamap_t tulip_alloc_rxmap(tulip_softc_t *); +void tulip_free_rxmap(tulip_softc_t *, bus_dmamap_t); +bus_dmamap_t tulip_alloc_txmap(tulip_softc_t *); +void tulip_free_txmap(tulip_softc_t *, bus_dmamap_t); void tulip_timeout_callback(void *arg) @@ -2859,6 +2863,30 @@ tulip_ifmedia_status(struct ifnet * const ifp, struct ifmediareq *req) req->ifm_active = tulip_media_to_ifmedia[sc->tulip_media]; } +bus_dmamap_t +tulip_alloc_rxmap(tulip_softc_t *sc) +{ + return (sc->tulip_free_rxmaps[--sc->tulip_num_free_rxmaps]); +} + +void +tulip_free_rxmap(tulip_softc_t *sc, bus_dmamap_t map) +{ + sc->tulip_free_rxmaps[sc->tulip_num_free_rxmaps++] = map; +} + +bus_dmamap_t +tulip_alloc_txmap(tulip_softc_t *sc) +{ + return (sc->tulip_free_txmaps[--sc->tulip_num_free_txmaps]); +} + +void +tulip_free_txmap(tulip_softc_t *sc, bus_dmamap_t map) +{ + sc->tulip_free_txmaps[sc->tulip_num_free_txmaps++] = map; +} + void tulip_addr_filter(tulip_softc_t * const sc) { @@ -3048,7 +3076,7 @@ tulip_reset(tulip_softc_t * const sc) break; map = TULIP_GETCTX(m, bus_dmamap_t); bus_dmamap_unload(sc->tulip_dmatag, map); - sc->tulip_txmaps[sc->tulip_txmaps_free++] = map; + tulip_free_txmap(sc, map); m_freem(m); } @@ -3086,7 +3114,7 @@ tulip_reset(tulip_softc_t * const sc) break; map = TULIP_GETCTX(m, bus_dmamap_t); bus_dmamap_unload(sc->tulip_dmatag, map); - sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map; + tulip_free_rxmap(sc, map); m_freem(m); } @@ -3242,12 +3270,9 @@ tulip_rx_intr(tulip_softc_t * const sc) IF_DEQUEUE(&sc->tulip_rxq, ms); for (me = ms; total_len > 0; total_len--) { map = TULIP_GETCTX(me, bus_dmamap_t); -#ifdef __alpha__ - if (map->_dm_window != NULL) -#endif TULIP_RXMAP_POSTSYNC(sc, map); bus_dmamap_unload(sc->tulip_dmatag, map); - sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map; + tulip_free_rxmap(sc, map); #if defined(DIAGNOSTIC) TULIP_SETCTX(me, NULL); #endif @@ -3270,7 +3295,7 @@ tulip_rx_intr(tulip_softc_t * const sc) bus_dmamap_sync(sc->tulip_dmatag, map, 0, me->m_len, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->tulip_dmatag, map); - sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map; + tulip_free_rxmap(sc, map); #if defined(DIAGNOSTIC) TULIP_SETCTX(me, NULL); #endif @@ -3318,7 +3343,7 @@ tulip_rx_intr(tulip_softc_t * const sc) map = TULIP_GETCTX(me, bus_dmamap_t); bus_dmamap_unload(sc->tulip_dmatag, map); - sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map; + tulip_free_rxmap(sc, map); #if defined(DIAGNOSTIC) TULIP_SETCTX(me, NULL); #endif @@ -3399,9 +3424,9 @@ tulip_rx_intr(tulip_softc_t * const sc) */ do { tulip_desc_t * const nextout = ri->ri_nextout; - if (sc->tulip_rxmaps_free > 0) - map = sc->tulip_rxmaps[--sc->tulip_rxmaps_free]; - else { + if (sc->tulip_num_free_rxmaps > 0) { + map = tulip_alloc_rxmap(sc); + } else { m_freem(ms); sc->tulip_flags |= TULIP_RXBUFSLOW; #if defined(TULIP_DEBUG) @@ -3493,11 +3518,8 @@ tulip_tx_intr(tulip_softc_t * const sc) IF_DEQUEUE(&sc->tulip_txq, m); if (m != NULL) { bus_dmamap_t map = TULIP_GETCTX(m, bus_dmamap_t); -#ifdef __alpha__ - if (map->_dm_window != NULL) -#endif TULIP_TXMAP_POSTSYNC(sc, map); - sc->tulip_txmaps[sc->tulip_txmaps_free++] = map; + tulip_free_txmap(sc, map); #if NBPFILTER > 0 if (sc->tulip_bpf != NULL) bpf_mtap(sc->tulip_if.if_bpf, m, BPF_DIRECTION_OUT); @@ -3844,14 +3866,14 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m) /* * Reclaim some DMA maps from if we are out. */ - if (sc->tulip_txmaps_free == 0) { + if (sc->tulip_num_free_txmaps == 0) { #if defined(TULIP_DEBUG) sc->tulip_dbg.dbg_no_txmaps++; #endif freedescs += tulip_tx_intr(sc); } - if (sc->tulip_txmaps_free > 0) - map = sc->tulip_txmaps[sc->tulip_txmaps_free-1]; + if (sc->tulip_num_free_txmaps > 0) + map = tulip_alloc_txmap(sc); else { sc->tulip_flags |= TULIP_WANTTXSTART; #if defined(TULIP_DEBUG) @@ -3892,6 +3914,7 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m) #if defined(TULIP_DEBUG) sc->tulip_dbg.dbg_txput_finishes[2]++; #endif + tulip_free_txmap(sc, map); goto finish; } error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT); @@ -3902,6 +3925,7 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m) #if defined(TULIP_DEBUG) sc->tulip_dbg.dbg_txput_finishes[3]++; #endif + tulip_free_txmap(sc, map); goto finish; } } @@ -3921,6 +3945,7 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m) sc->tulip_dbg.dbg_txput_finishes[4]++; #endif bus_dmamap_unload(sc->tulip_dmatag, map); + tulip_free_txmap(sc, map); goto finish; } for (; map->dm_nsegs - segcnt > 1; segcnt += 2) { @@ -3949,7 +3974,6 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m) TULIP_TXMAP_PRESYNC(sc, map); TULIP_SETCTX(m, map); map = NULL; - --sc->tulip_txmaps_free; /* commit to using the dmamap */ /* * The descriptors have been filled in. Now get ready @@ -4408,18 +4432,18 @@ tulip_busdma_init(tulip_softc_t * const sc) } /* - * Allocate dmamaps for each transmit descriptors + * Allocate dmamaps for each transmit descriptor, and place on the + * free list. */ if (error == 0) { - while (error == 0 && sc->tulip_txmaps_free < TULIP_TXDESCS) { + while (error == 0 && sc->tulip_num_free_txmaps < TULIP_TXDESCS) { bus_dmamap_t map; if ((error = TULIP_TXMAP_CREATE(sc, &map)) == 0) - sc->tulip_txmaps[sc->tulip_txmaps_free++] = map; + tulip_free_txmap(sc, map); } if (error) { - while (sc->tulip_txmaps_free > 0) - bus_dmamap_destroy(sc->tulip_dmatag, - sc->tulip_txmaps[--sc->tulip_txmaps_free]); + while (sc->tulip_num_free_txmaps > 0) + bus_dmamap_destroy(sc->tulip_dmatag, tulip_alloc_txmap(sc)); } } @@ -4433,18 +4457,18 @@ tulip_busdma_init(tulip_softc_t * const sc) } /* - * Allocate dmamaps for each receive descriptors + * Allocate dmamaps for each receive descriptor, and place on the + * free list. */ if (error == 0) { - while (error == 0 && sc->tulip_rxmaps_free < TULIP_RXDESCS) { + while (error == 0 && sc->tulip_num_free_rxmaps < TULIP_RXDESCS) { bus_dmamap_t map; if ((error = TULIP_RXMAP_CREATE(sc, &map)) == 0) - sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map; + tulip_free_rxmap(sc, map); } if (error) { - while (sc->tulip_rxmaps_free > 0) - bus_dmamap_destroy(sc->tulip_dmatag, - sc->tulip_rxmaps[--sc->tulip_rxmaps_free]); + while (sc->tulip_num_free_rxmaps > 0) + bus_dmamap_destroy(sc->tulip_dmatag, tulip_alloc_rxmap(sc)); } } return (error); diff --git a/sys/dev/pci/if_devar.h b/sys/dev/pci/if_devar.h index 716d45628ef..3d2578339d5 100644 --- a/sys/dev/pci/if_devar.h +++ b/sys/dev/pci/if_devar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_devar.h,v 1.29 2008/08/15 15:49:08 naddy Exp $ */ +/* $OpenBSD: if_devar.h,v 1.30 2009/06/19 14:13:41 naddy Exp $ */ /* $NetBSD: if_devar.h,v 1.13 1997/06/08 18:46:36 thorpej Exp $ */ /*- @@ -435,11 +435,11 @@ struct _tulip_softc_t { bus_dma_tag_t tulip_dmatag; /* bus DMA tag */ bus_dmamap_t tulip_setupmap; bus_dmamap_t tulip_txdescmap; - bus_dmamap_t tulip_txmaps[TULIP_TXDESCS]; - unsigned tulip_txmaps_free; + bus_dmamap_t tulip_free_txmaps[TULIP_TXDESCS]; + unsigned tulip_num_free_txmaps; bus_dmamap_t tulip_rxdescmap; - bus_dmamap_t tulip_rxmaps[TULIP_RXDESCS]; - unsigned tulip_rxmaps_free; + bus_dmamap_t tulip_free_rxmaps[TULIP_RXDESCS]; + unsigned tulip_num_free_rxmaps; struct arpcom tulip_ac; struct timeout tulip_ftmo, tulip_stmo; tulip_regfile_t tulip_csrs; |