kern/115586: options IPSEC disables TSO

Andrew Gallatin gallatin at cs.duke.edu
Thu Aug 16 13:30:03 PDT 2007


>Number:         115586
>Category:       kern
>Synopsis:       options IPSEC disables TSO
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Aug 16 20:30:02 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Andrew Gallatin
>Release:        7.0-CURRENT
>Organization:
Myricom
>Environment:
FreeBSD venice 7.0-CURRENT FreeBSD 7.0-CURRENT #4: Thu Aug 16 15:46:45 EDT 2007     gallatin at venice:/usr/src/sys/amd64/compile/IPSEC  amd64

>Description:
Simply compiling IPSEC into the kernel causes TCP Segmentation Offload
to be silently disabled for all connections, not just connections using IPSEC.
This causes a severe performance loss, especially on 10GbE networks.
>How-To-Repeat:
- Compile a kernel with 'options IPSEC' and device crypto
- boot the kernel
- notice that TSO stops working (can be verified by watching
the number of packets sent via systat -tcp 1)
>Fix:
A *hack*, not a fix, is attached.  The hack enables normal connections to do TSO even when IPSEC is compiled in.  Essentially, the TSO code needs to be a bit smarter, and check for more than just a null tp->t_inpcb->inp_sp.  I know nothing about IPSEC, so I'm not able to propose a real fix.

Patch attached with submission follows:

Index: netinet/tcp_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.140
diff -u -r1.140 tcp_output.c
--- netinet/tcp_output.c	3 Jul 2007 12:13:43 -0000	1.140
+++ netinet/tcp_output.c	16 Aug 2007 19:46:09 -0000
@@ -459,8 +459,8 @@
 		    ((tp->t_flags & TF_SIGNATURE) == 0) &&
 		    tp->rcv_numsacks == 0 && sack_rxmit == 0 &&
 		    tp->t_inpcb->inp_options == NULL &&
-		    tp->t_inpcb->in6p_options == NULL &&
-		    tp->t_inpcb->inp_sp == NULL) {
+		    tp->t_inpcb->in6p_options == NULL /* &&
+		    tp->t_inpcb->inp_sp == NULL*/) {
 			tso = 1;
 		} else {
 			len = tp->t_maxseg;


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list