From ce6ba017fa9ccd40e341cf13a9e6f62dcaba3b19 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 6 Sep 2013 12:47:14 +0000 Subject: [PATCH] Fix the leakage of dma tags on if_arge. The leak occur when arge_start() add some packet(s) to tx ring and arge_stop() is called before receive the sent packet interrupt from hardware. Fix arge_stop() to unload the in use dma tags and free the associated mbuf. PR: 178319, 163670 Approved by: adrian (mentor) --- sys/mips/atheros/if_arge.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 21b945f3f6d..aabab52187b 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -142,6 +142,7 @@ static int arge_resume(device_t); static int arge_rx_ring_init(struct arge_softc *); static void arge_rx_ring_free(struct arge_softc *sc); static int arge_tx_ring_init(struct arge_softc *); +static void arge_tx_ring_free(struct arge_softc *); #ifdef DEVICE_POLLING static int arge_poll(struct ifnet *, enum poll_cmd, int); #endif @@ -1278,6 +1279,7 @@ arge_stop(struct arge_softc *sc) /* Flush FIFO and free any existing mbufs */ arge_flush_ddr(sc); arge_rx_ring_free(sc); + arge_tx_ring_free(sc); } @@ -1707,6 +1709,30 @@ arge_tx_ring_init(struct arge_softc *sc) return (0); } +/* + * Free the Tx ring, unload any pending dma transaction and free the mbuf. + */ +static void +arge_tx_ring_free(struct arge_softc *sc) +{ + struct arge_txdesc *txd; + int i; + + /* Free the Tx buffers. */ + for (i = 0; i < ARGE_TX_RING_COUNT; i++) { + txd = &sc->arge_cdata.arge_txdesc[i]; + if (txd->tx_dmamap) { + bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap); + } + if (txd->tx_m) + m_freem(txd->tx_m); + txd->tx_m = NULL; + } +} + /* * Initialize the RX descriptors and allocate mbufs for them. Note that * we arrange the descriptors in a closed ring, so that the last descriptor