diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2014-05-06 02:54:59 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2014-05-06 02:54:59 +0000 |
commit | 5bd3f1337e94b744dfde90346c2304d0b558ea8e (patch) | |
tree | cb656f3ec82ee4fa551ba4154ebc0883c1a6e0bf /sys | |
parent | a54326376af297e38afd4198c82690c12c6bd2a8 (diff) | |
download | FreeBSD-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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if.c | 4 |
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__)); |