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