Date: Thu, 17 Apr 2014 23:31:50 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r264630 - head/sys/net Message-ID: <201404172331.s3HNVovb011597@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Thu Apr 17 23:31:50 2014 New Revision: 264630 URL: http://svnweb.freebsd.org/changeset/base/264630 Log: For NFS mounts using rsize,wsize=65536 over TSO enabled network interfaces limited to 32 transmit segments, there are two known issues. The more serious one is that for an I/O of slightly less than 64K, the net device driver prepends an ethernet header, resulting in a TSO segment slightly larger than 64K. Since m_defrag() copies this into 33 mbuf clusters, the transmit fails with EFBIG. A tester indicated observing a similar failure using iSCSI. The second less critical problem is that the network device driver must copy the mbuf chain via m_defrag() (m_collapse() is not sufficient), resulting in measurable overhead. This patch reduces the default size of if_hw_tsomax slightly, so that the first issue is avoided. Fixing the second issue will require a way for the network device driver to inform tcp_output() that it is limited to 32 transmit segments. Reported and tested by: csforgeron@gmail.com, markus.gebert@hostpoint.ch MFC after: 2 weeks Modified: head/sys/net/if.c Modified: head/sys/net/if.c ============================================================================== --- head/sys/net/if.c Thu Apr 17 21:43:34 2014 (r264629) +++ head/sys/net/if.c Thu Apr 17 23:31:50 2014 (r264630) @@ -74,6 +74,7 @@ #include <net/vnet.h> #if defined(INET) || defined(INET6) +#include <net/ethernet.h> #include <netinet/in.h> #include <netinet/in_var.h> #include <netinet/ip.h> @@ -655,7 +656,8 @@ if_attach_internal(struct ifnet *ifp, in #if defined(INET) || defined(INET6) /* Initialize to max value. */ if (ifp->if_hw_tsomax == 0) - ifp->if_hw_tsomax = IP_MAXPACKET; + ifp->if_hw_tsomax = min(IP_MAXPACKET, 32 * MCLBYTES - + (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN)); KASSERT(ifp->if_hw_tsomax <= IP_MAXPACKET && ifp->if_hw_tsomax >= IP_MAXPACKET / 8, ("%s: tsomax outside of range", __func__));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404172331.s3HNVovb011597>