From owner-svn-src-all@FreeBSD.ORG  Mon Jul  7 08:22:39 2014
Return-Path: <owner-svn-src-all@FreeBSD.ORG>
Delivered-To: svn-src-all@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115])
 (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))
 (No client certificate requested)
 by hub.freebsd.org (Postfix) with ESMTPS id EBFB35CE;
 Mon,  7 Jul 2014 08:22:39 +0000 (UTC)
Received: from svn.freebsd.org (svn.freebsd.org
 [IPv6:2001:1900:2254:2068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mx1.freebsd.org (Postfix) with ESMTPS id BF0DB27E2;
 Mon,  7 Jul 2014 08:22:39 +0000 (UTC)
Received: from svn.freebsd.org ([127.0.1.70])
 by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s678MdSa036700;
 Mon, 7 Jul 2014 08:22:39 GMT (envelope-from fabient@svn.freebsd.org)
Received: (from fabient@localhost)
 by svn.freebsd.org (8.14.8/8.14.8/Submit) id s678MdLd036699;
 Mon, 7 Jul 2014 08:22:39 GMT (envelope-from fabient@svn.freebsd.org)
Message-Id: <201407070822.s678MdLd036699@svn.freebsd.org>
From: Fabien Thomas <fabient@FreeBSD.org>
Date: Mon, 7 Jul 2014 08:22:39 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-all@freebsd.org,
 svn-src-head@freebsd.org
Subject: svn commit: r268359 - head/sys/dev/mge
X-SVN-Group: head
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-all@freebsd.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: "SVN commit messages for the entire src tree \(except for &quot;
 user&quot; and &quot; projects&quot; \)" <svn-src-all.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-all>,
 <mailto:svn-src-all-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-all/>
List-Post: <mailto:svn-src-all@freebsd.org>
List-Help: <mailto:svn-src-all-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-all>,
 <mailto:svn-src-all-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Mon, 07 Jul 2014 08:22:40 -0000

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);
 	}