Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Aug 2002 15:36:38 -0400 (EDT)
From:      Andrew Gallatin <gallatin@cs.duke.edu>
To:        Luigi Rizzo <rizzo@icir.org>
Cc:        freebsd-net@FreeBSD.ORG
Subject:   Re: m_getcl and end-to-end performance
Message-ID:  <15714.39494.661931.882244@grasshopper.cs.duke.edu>
In-Reply-To: <20020820093939.B48541@iguana.icir.org>
References:  <15714.27671.533860.408996@grasshopper.cs.duke.edu> <20020820093939.B48541@iguana.icir.org>

next in thread | previous in thread | raw e-mail | index | archive | help

Luigi Rizzo writes:
 > 
 > now if you have patches i'll be happy to have a look at them.

Here's what I'm running with now.  It removes the M_PKTHDR
requirement, allowing me to use multiple m_getcl()'s to stock jumbo
frames. 

The uicp_socket.c is just a cheesey hack to soreceive() so as to
pretend we do mcl_pool restocking in m_free().

For a netperf UDP_STREAM, I see ~1,000 to ~2,000 packets/sec increase
in throughput for sizes 256 through 2K.  For large (8K) I see a
~20-30Mb/sec increase (but that's only a few hundred pkts/sec).

Drew


Index: uipc_mbuf.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.51.2.20
diff -u -r1.51.2.20 uipc_mbuf.c
--- uipc_mbuf.c	12 Aug 2002 22:09:12 -0000	1.51.2.20
+++ uipc_mbuf.c	20 Aug 2002 19:08:38 -0000
@@ -569,20 +569,22 @@
 	int s = splimp();
 	struct mbuf *mp;
 
+	if (type == MT_DATA && mcl_pool) {
+		mp = mcl_pool;
+		mcl_pool = mp->m_nextpkt;
+		mcl_pool_now--;
+		splx(s);
+		mp->m_nextpkt = NULL;
+		mp->m_data = mp->m_ext.ext_buf;
+		mp->m_flags = flags|M_EXT;
+		mp->m_pkthdr.rcvif = NULL;
+		mp->m_pkthdr.csum_flags = 0;
+		mp->m_pkthdr.aux = NULL;
+		return mp;
+	}
+
 	if (flags & M_PKTHDR) {
-		if (type == MT_DATA && mcl_pool) {
-			mp = mcl_pool;
-			mcl_pool = mp->m_nextpkt;
-			mcl_pool_now--;
-			splx(s);
-			mp->m_nextpkt = NULL;
-			mp->m_data = mp->m_ext.ext_buf;
-			mp->m_flags = M_PKTHDR|M_EXT;
-			mp->m_pkthdr.rcvif = NULL;
-			mp->m_pkthdr.csum_flags = 0;
-			return mp;
-		} else
-			MGETHDR(mp, how, type);
+		MGETHDR(mp, how, type);
 	} else
 		MGET(mp, how, type);
 	if (mp) {
@@ -704,32 +706,36 @@
 m_freem(m)
 	struct mbuf *m;
 {
+	struct mbuf *m_tmp;
 	int s = splimp();
 
 	/*
 	 * Try to keep a small pool of mbuf+cluster for quick use in
 	 * device drivers. A good candidate is a M_PKTHDR buffer with
-	 * only one cluster attached. Other mbufs, or those exceeding
+	 * at least one cluster attached. Other mbufs, or those exceeding
 	 * the pool size, are just m_free'd in the usual way.
 	 * The following code makes sure that m_next, m_type,
 	 * m_pkthdr.aux and m_ext.* are properly initialized.
 	 * Other fields in the mbuf are initialized in m_getcl()
 	 * upon allocation.
 	 */
-        if (mcl_pool_now < mcl_pool_max && m && m->m_next == NULL &&
-            (m->m_flags & (M_PKTHDR|M_EXT)) == (M_PKTHDR|M_EXT) &&
+        if (mcl_pool_now < mcl_pool_max && m && 
+            (m->m_flags & M_EXT) == M_EXT &&
             m->m_type == MT_DATA && M_EXT_WRITABLE(m) ) {
-		if (m->m_pkthdr.aux) {
+		m_tmp = m->m_next;
+		m->m_next = NULL;
+		if ((m->m_flags & M_PKTHDR) == M_PKTHDR &&
+		    m->m_pkthdr.aux) {
 			m_freem(m->m_pkthdr.aux);
-			m->m_pkthdr.aux = NULL;
 		}
                 m->m_nextpkt = mcl_pool;
                 mcl_pool = m;
                 mcl_pool_now++;
-        } else {
-		while (m)
-			m = m_free(m);
-	}
+		m = m_tmp;
+	} 
+	while (m)
+		m = m_free(m);
+
 	splx(s);
 }
 
Index: uipc_socket.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.68.2.21
diff -u -r1.68.2.21 uipc_socket.c
--- uipc_socket.c	1 May 2002 03:27:35 -0000	1.68.2.21
+++ uipc_socket.c	20 Aug 2002 16:14:06 -0000
@@ -865,7 +865,13 @@
 					so->so_rcv.sb_mb = m = m->m_next;
 					*mp = (struct mbuf *)0;
 				} else {
-					so->so_rcv.sb_mb = m = m_free(m);
+					struct mbuf *m_tmp;
+
+					m_tmp = m->m_next;
+					m->m_next = NULL;
+/*					so->so_rcv.sb_mb = m = m_free(m);*/
+					m_freem (m);
+					so->so_rcv.sb_mb = m = m_tmp;
 				}
 				if (m)
 					m->m_nextpkt = nextrecord;

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?15714.39494.661931.882244>