Date: Tue, 10 Apr 2007 10:23:23 +0900 From: Pyun YongHyeon <pyunyh@gmail.com> To: Harald Schmalzbauer <harry@schmalzbauer.de> Cc: freebsd-bugs@FreeBSD.org Subject: Re: kern/111384: msk hw checksum problem Message-ID: <20070410012323.GB45776@cdnetworks.co.kr> In-Reply-To: <20070409062618.GA41379@cdnetworks.co.kr> References: <200704082120.l38LKA3v058525@freefall.freebsd.org> <20070409062618.GA41379@cdnetworks.co.kr>
next in thread | previous in thread | raw e-mail | index | archive | help
--9amGYk9869ThD9tj Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, Apr 09, 2007 at 03:26:18PM +0900, To Harald Schmalzbauer wrote: > On Sun, Apr 08, 2007 at 09:20:10PM +0000, Harald Schmalzbauer wrote: > > The following reply was made to PR kern/111384; it has been noted by GNATS. > > > > From: Harald Schmalzbauer <harry@schmalzbauer.de> > > To: FreeBSD-gnats-submit@freebsd.org, freebsd-bugs@freebsd.org > > Cc: > > Subject: Re: kern/111384: msk hw checksum problem > > Date: Sun, 8 Apr 2007 22:58:12 +0200 > > > > I did a quick check on 6.2-stable and couldn't see the symptom (no connection > > to freeshports). But I haven't captured traffic, so I can't guarantee that > > the "TCP checksum mismatch" doesn't aplly to 6.2-stable as well. > > > > Hmm, it's odd that STABLE works wihtout issues. msk(4) in STABLE > takes the same code path so it shoud have the issue too if msk(4) in > HEAD also has checksum offload issues. > > The reason of sending Winwdos probe message comes from the other > party' zero window advertisement in SYN + ACK packet. As you know > TCP can't send more data except window probing message if it recevied > zero window advirtisement. > Maybe the other party(www.freshports.org) advertise its window update > packet if it received correct window probe message from msk(4). > Since msk(4) failed to generate correct TCP cheksum the other party > didn't receive the probe message and you've lost connection here. > > Anyway I was able to reproduce the issue on HEAD but I have no idea > atm. Just padding with zeros to make it 60 bytes frame didn't work and > I wonder how it could work in STABLE. > Please try attached patch and let me know the result. -- Regards, Pyun YongHyeon --9amGYk9869ThD9tj Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="if_msk.chksum.patch" Index: if_msk.c =================================================================== RCS file: /home/ncvs/src/sys/dev/msk/if_msk.c,v retrieving revision 1.12 diff -u -r1.12 if_msk.c --- if_msk.c 6 Apr 2007 02:02:07 -0000 1.12 +++ if_msk.c 10 Apr 2007 01:19:23 -0000 @@ -131,6 +131,7 @@ #include <netinet/udp.h> #include <machine/bus.h> +#include <machine/in_cksum.h> #include <machine/resource.h> #include <sys/rman.h> @@ -2647,7 +2648,6 @@ * hardware. However, TSO performance of Yukon II is very * good such that it's worth to implement it. */ - struct ether_vlan_header *evh; struct ether_header *eh; struct ip *ip; struct tcphdr *tcp; @@ -2669,17 +2669,37 @@ *m_head = NULL; return (ENOBUFS); } - evh = mtod(m, struct ether_vlan_header *); - ip = (struct ip *)(evh + 1); - } else - ip = (struct ip *)(eh + 1); + } m = m_pullup(m, offset + sizeof(struct ip)); if (m == NULL) { *m_head = NULL; return (ENOBUFS); } + ip = (struct ip *)(mtod(m, char *) + offset); offset += (ip->ip_hl << 2); tcp_offset = offset; + /* + * It seems that Yukon II has Tx checksum offload bug for + * small TCP packets that's less than 60 bytes in size + * (e.g. TCP window probe packet, pure ACK packet). + * Common work around like padding with zeros to make the + * frame minimum ethernet frame size didn't work at all. + * Instead of disabling checksum offload completely we + * resort to S/W checksum routine when we encounter short + * TCP frames. + * Short UDP packets appear to be handled correctly by + * Yukon II. + */ + if (m->m_pkthdr.len < MSK_MIN_FRAMELEN && + (m->m_pkthdr.csum_flags & CSUM_TCP) != 0) { + uint16_t csum; + + csum = in_cksum_skip(m, ntohs(ip->ip_len) + offset - + (ip->ip_hl << 2), offset); + *(uint16_t *)(m->m_data + offset + + m->m_pkthdr.csum_data) = csum; + m->m_pkthdr.csum_flags &= ~CSUM_TCP; + } if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) { m = m_pullup(m, offset + sizeof(struct tcphdr)); if (m == NULL) { --9amGYk9869ThD9tj--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070410012323.GB45776>