summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2014-05-06 02:54:59 +0000
committerrmacklem <rmacklem@FreeBSD.org>2014-05-06 02:54:59 +0000
commit5bd3f1337e94b744dfde90346c2304d0b558ea8e (patch)
treecb656f3ec82ee4fa551ba4154ebc0883c1a6e0bf
parenta54326376af297e38afd4198c82690c12c6bd2a8 (diff)
downloadFreeBSD-src-5bd3f1337e94b744dfde90346c2304d0b558ea8e.zip
FreeBSD-src-5bd3f1337e94b744dfde90346c2304d0b558ea8e.tar.gz
MFC: r264630
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.
-rw-r--r--sys/net/if.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 0356ec7..ea2aa85 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -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>
@@ -658,7 +659,8 @@ if_attach_internal(struct ifnet *ifp, int vmove)
#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__));
OpenPOWER on IntegriCloud