svn commit: r268359 - head/sys/dev/mge
Fabien Thomas
fabient at FreeBSD.org
Mon Jul 7 08:22:40 UTC 2014
Author: fabient
Date: Mon Jul 7 08:22:39 2014
New Revision: 268359
URL: http://svnweb.freebsd.org/changeset/base/268359
Log:
Optim and Fix for mge driver:
- add missing rcvif in mbuf
- add missing ipacket stat
- remove uncessary mbuf copy on output path
- fix deadlock of the TX engine in case of error
Obtained from: NETASQ
MFC after: 2 weeks
Modified:
head/sys/dev/mge/if_mge.c
Modified: head/sys/dev/mge/if_mge.c
==============================================================================
--- head/sys/dev/mge/if_mge.c Mon Jul 7 06:37:14 2014 (r268358)
+++ head/sys/dev/mge/if_mge.c Mon Jul 7 08:22:39 2014 (r268359)
@@ -1140,6 +1140,8 @@ mge_intr_rx_locked(struct mge_softc *sc,
mb->m_pkthdr.len -= 2;
mb->m_data += 2;
+ mb->m_pkthdr.rcvif = ifp;
+
mge_offload_process_frame(ifp, mb, status,
bufsize);
@@ -1159,6 +1161,8 @@ mge_intr_rx_locked(struct mge_softc *sc,
count -= 1;
}
+ ifp->if_ipackets += rx_npkts;
+
return (rx_npkts);
}
@@ -1437,12 +1441,6 @@ mge_encap(struct mge_softc *sc, struct m
ifp = sc->ifp;
- /* Check for free descriptors */
- if (sc->tx_desc_used_count + 1 >= MGE_TX_DESC_NUM) {
- /* No free descriptors */
- return (-1);
- }
-
/* Fetch unused map */
desc_no = sc->tx_desc_curr;
dw = &sc->mge_tx_desc[desc_no];
@@ -1451,9 +1449,16 @@ mge_encap(struct mge_softc *sc, struct m
/* Create mapping in DMA memory */
error = bus_dmamap_load_mbuf_sg(sc->mge_tx_dtag, mapp, m0, segs, &nsegs,
BUS_DMA_NOWAIT);
- if (error != 0 || nsegs != 1 ) {
+ if (error != 0) {
+ m_freem(m0);
+ return (error);
+ }
+
+ /* Only one segment is supported. */
+ if (nsegs != 1) {
bus_dmamap_unload(sc->mge_tx_dtag, mapp);
- return ((error != 0) ? error : -1);
+ m_freem(m0);
+ return (-1);
}
bus_dmamap_sync(sc->mge_tx_dtag, mapp, BUS_DMASYNC_PREWRITE);
@@ -1553,15 +1558,33 @@ mge_start_locked(struct ifnet *ifp)
if (m0 == NULL)
break;
- mtmp = m_defrag(m0, M_NOWAIT);
- if (mtmp)
- m0 = mtmp;
+ if (m0->m_pkthdr.csum_flags & (CSUM_IP|CSUM_TCP|CSUM_UDP) ||
+ m0->m_flags & M_VLANTAG) {
+ if (M_WRITABLE(m0) == 0) {
+ mtmp = m_dup(m0, M_NOWAIT);
+ m_freem(m0);
+ if (mtmp == NULL)
+ continue;
+ m0 = mtmp;
+ }
+ }
+ /* The driver support only one DMA fragment. */
+ if (m0->m_next != NULL) {
+ mtmp = m_defrag(m0, M_NOWAIT);
+ if (mtmp)
+ m0 = mtmp;
+ }
- if (mge_encap(sc, m0)) {
+ /* Check for free descriptors */
+ if (sc->tx_desc_used_count + 1 >= MGE_TX_DESC_NUM) {
IF_PREPEND(&ifp->if_snd, m0);
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
+
+ if (mge_encap(sc, m0) != 0)
+ break;
+
queued++;
BPF_MTAP(ifp, m0);
}
More information about the svn-src-head
mailing list