summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authorloos <loos@FreeBSD.org>2013-09-06 12:47:14 +0000
committerloos <loos@FreeBSD.org>2013-09-06 12:47:14 +0000
commit3263427a2eb3c2dcf28cdcc849a9b31fa8db4895 (patch)
tree7e7b79970afd83d0421d0c44a09435fb320fad7e /sys/mips
parent63750491ac270cc819615c6479c8fdaa65916dc4 (diff)
downloadFreeBSD-src-3263427a2eb3c2dcf28cdcc849a9b31fa8db4895.zip
FreeBSD-src-3263427a2eb3c2dcf28cdcc849a9b31fa8db4895.tar.gz
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)
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/atheros/if_arge.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c
index 21b945f..aabab52 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);
}
@@ -1708,6 +1710,30 @@ arge_tx_ring_init(struct arge_softc *sc)
}
/*
+ * 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
* points back to the first.
OpenPOWER on IntegriCloud