tcp: Use mbuf jcluster (4K) in sosendtcp(); improve 10Ge TSO performance
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 13 Sep 2013 09:26:22 +0000 (17:26 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 13 Sep 2013 09:37:50 +0000 (17:37 +0800)
For the Myricom PCIE-8AL-C I have tested, this gives ~900Mbps performance
boost using 1500 MTU when TSO is enabled (from 7.7Gbps to 8.6Gbps).

Using mbuf jcluster could:
- Reduce the number of TX descriptors needed for one TSO packet.
- Let the NIC chip perform longer large data burst.

I believe this is the main reasons for the 10Ge performance boost.

Reduce sosend_agglim from 3 to 2, which means 8K aggregation (was 6K
aggregation) before user thread dispatches the sending buf to netisr.

net.inet.tcp.sosend_jcluster is added to enable this feature; it is
enabled by default.

sys/kern/uipc_socket.c
sys/netinet/tcp_input.c

index 25554d1..162ac33 100644 (file)
@@ -99,6 +99,7 @@
 #ifdef INET
 extern int tcp_sosend_agglim;
 extern int tcp_sosend_async;
+extern int tcp_sosend_jcluster;
 extern int udp_sosend_async;
 extern int udp_sosend_prepend;
 
@@ -1184,8 +1185,13 @@ restart:
                    } else do {
                        if (resid > INT_MAX)
                                resid = INT_MAX;
-                       m = m_getl((int)resid, MB_WAIT, MT_DATA,
-                                  top == NULL ? M_PKTHDR : 0, &mlen);
+                       if (tcp_sosend_jcluster) {
+                               m = m_getlj((int)resid, MB_WAIT, MT_DATA,
+                                          top == NULL ? M_PKTHDR : 0, &mlen);
+                       } else {
+                               m = m_getl((int)resid, MB_WAIT, MT_DATA,
+                                          top == NULL ? M_PKTHDR : 0, &mlen);
+                       }
                        if (top == NULL) {
                                m->m_pkthdr.len = 0;
                                m->m_pkthdr.rcvif = NULL;
index 4e12d87..e2dfa59 100644 (file)
@@ -251,7 +251,7 @@ int tcp_autorcvbuf_max = 2*1024*1024;
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, recvbuf_max, CTLFLAG_RW,
     &tcp_autorcvbuf_max, 0, "Max size of automatic receive buffer");
 
-int tcp_sosend_agglim = 3;
+int tcp_sosend_agglim = 2;
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, sosend_agglim, CTLFLAG_RW,
     &tcp_sosend_agglim, 0, "TCP sosend mbuf aggregation limit");
 
@@ -259,6 +259,10 @@ int tcp_sosend_async = 1;
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, sosend_async, CTLFLAG_RW,
     &tcp_sosend_async, 0, "TCP asynchronized pru_send");
 
+int tcp_sosend_jcluster = 1;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, sosend_jcluster, CTLFLAG_RW,
+    &tcp_sosend_jcluster, 0, "TCP output uses jcluster");
+
 static int tcp_ignore_redun_dsack = 1;
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, ignore_redun_dsack, CTLFLAG_RW,
     &tcp_ignore_redun_dsack, 0, "Ignore redundant DSACK");