Date: Thu, 29 Sep 2011 16:25:06 +0100 From: Ben Hutchings <bhutchings@solarflare.com> To: freebsd-net@freebsd.org Subject: TSO broken with jumbo MTU Message-ID: <1317309906.2743.9.camel@bwh-desktop>
next in thread | raw e-mail | index | archive | help
tcp_output() does: if (... && len > tp->t_maxseg && ...) tso = 1; Then: if (len + optlen + ipoptlen > tp->t_maxopd) { ... if (tso) { ... if (sendalot && off + len < so->so_snd.sb_cc) { len -= len % (tp->t_maxopd - optlen); sendalot = 1; } Then later: if (tso) { KASSERT(len > tp->t_maxopd - optlen, ("%s: len <= tso_segsz", __func__)); m->m_pkthdr.csum_flags |= CSUM_TSO; m->m_pkthdr.tso_segsz = tp->t_maxopd - optlen; } So there is an assumption here that tp->t_maxseg >= tp->t_maxopd - optlen. But tcp_mss_update() does not ensure that at all, because it rounds down tp->t_maxseg to a multiple of MCLBYTES and does not change tp->t_maxopd accordingly: tp->t_maxopd = mss; if (...) mss -= TCPOLEN_TSTAMP_APPA; #if (MCLBYTES & (MCLBYTES - 1)) == 0 if (mss > MCLBYTES) mss &= ~(MCLBYTES-1); #else if (mss > MCLBYTES) mss = mss / MCLBYTES * MCLBYTES; #endif tp->t_maxseg = mss; (All the above code is from 9, but I found the assertion failure on 8.2 which has fairly similar code.) Ben. -- Ben Hutchings, Staff Engineer, Solarflare Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1317309906.2743.9.camel>