Fix an mbuf leak in cpsw driver, clean up mbuf management:
* Record TX mbufs when we get them so we can release them. * Set TX/RX mbuf slots to NULL when we are no longer responsible for them * Move dma sync on RX into RX intr routine
This commit is contained in:
parent
e6f3cb32cc
commit
83e5430018
@ -522,11 +522,6 @@ cpsw_new_rxbuf(struct cpsw_softc *sc, uint32_t i, uint32_t next)
|
|||||||
int error;
|
int error;
|
||||||
int nsegs;
|
int nsegs;
|
||||||
|
|
||||||
if (sc->rx_mbuf[i]) {
|
|
||||||
bus_dmamap_sync(sc->mbuf_dtag, sc->rx_dmamap[i], BUS_DMASYNC_POSTREAD);
|
|
||||||
bus_dmamap_unload(sc->mbuf_dtag, sc->rx_dmamap[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
sc->rx_mbuf[i] = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
sc->rx_mbuf[i] = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||||
if (sc->rx_mbuf[i] == NULL)
|
if (sc->rx_mbuf[i] == NULL)
|
||||||
return (ENOBUFS);
|
return (ENOBUFS);
|
||||||
@ -593,6 +588,7 @@ cpsw_encap(struct cpsw_softc *sc, struct mbuf *m0)
|
|||||||
|
|
||||||
/* Write descriptor */
|
/* Write descriptor */
|
||||||
cpsw_cpdma_write_txbd(idx, &bd);
|
cpsw_cpdma_write_txbd(idx, &bd);
|
||||||
|
sc->tx_mbuf[idx] = m0;
|
||||||
|
|
||||||
/* Previous descriptor should point to us */
|
/* Previous descriptor should point to us */
|
||||||
cpsw_cpdma_write_txbd_next(((idx-1<0)?(CPSW_MAX_TX_BUFFERS-1):(idx-1)),
|
cpsw_cpdma_write_txbd_next(((idx-1<0)?(CPSW_MAX_TX_BUFFERS-1):(idx-1)),
|
||||||
@ -821,9 +817,15 @@ cpsw_intr_rx_locked(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bus_dmamap_sync(sc->mbuf_dtag,
|
||||||
|
sc->rx_dmamap[i],
|
||||||
|
BUS_DMASYNC_POSTREAD);
|
||||||
|
bus_dmamap_unload(sc->mbuf_dtag, sc->rx_dmamap[i]);
|
||||||
|
|
||||||
/* Handover packet */
|
/* Handover packet */
|
||||||
CPSW_RX_UNLOCK(sc);
|
CPSW_RX_UNLOCK(sc);
|
||||||
(*ifp->if_input)(ifp, sc->rx_mbuf[i]);
|
(*ifp->if_input)(ifp, sc->rx_mbuf[i]);
|
||||||
|
sc->rx_mbuf[i] = NULL;
|
||||||
CPSW_RX_LOCK(sc);
|
CPSW_RX_LOCK(sc);
|
||||||
|
|
||||||
/* Allocate new buffer for current descriptor */
|
/* Allocate new buffer for current descriptor */
|
||||||
@ -890,6 +892,7 @@ cpsw_intr_tx_locked(void *arg)
|
|||||||
BUS_DMASYNC_POSTWRITE);
|
BUS_DMASYNC_POSTWRITE);
|
||||||
bus_dmamap_unload(sc->mbuf_dtag, sc->tx_dmamap[sc->txbd_head]);
|
bus_dmamap_unload(sc->mbuf_dtag, sc->tx_dmamap[sc->txbd_head]);
|
||||||
m_freem(sc->tx_mbuf[sc->txbd_head]);
|
m_freem(sc->tx_mbuf[sc->txbd_head]);
|
||||||
|
sc->tx_mbuf[sc->txbd_head] = NULL;
|
||||||
|
|
||||||
cpsw_write_4(CPSW_CPDMA_TX_CP(0), cpsw_cpdma_txbd_paddr(sc->txbd_head));
|
cpsw_write_4(CPSW_CPDMA_TX_CP(0), cpsw_cpdma_txbd_paddr(sc->txbd_head));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user