Date: Sun, 22 Jun 1997 08:30:01 -0700 (PDT) From: Peter Wemm <peter@spinner.dialix.com.au> To: freebsd-bugs Subject: Re: kern/3925: SO_SNDLOWAT of 0 causes kernel to use 99% of CPU time on TCP send Message-ID: <199706221530.IAA06836@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/3925; it has been noted by GNATS. From: Peter Wemm <peter@spinner.dialix.com.au> To: sthaug@nethelp.no Cc: FreeBSD-gnats-submit@FreeBSD.ORG Subject: Re: kern/3925: SO_SNDLOWAT of 0 causes kernel to use 99% of CPU time on TCP send Date: Sun, 22 Jun 1997 23:20:44 +0800 When setting the parameters, there is no validity checking: case SO_SNDBUF: case SO_RCVBUF: if (sbreserve(optname == SO_SNDBUF ? &so->so_snd : &so->so_rcv, (u_long) *mtod(m, int *)) == 0) { error = ENOBUFS; goto bad; } break; case SO_SNDLOWAT: so->so_snd.sb_lowat = *mtod(m, int *); break; case SO_RCVLOWAT: so->so_rcv.sb_lowat = *mtod(m, int *); break; } However, soreserve() clips the results: soreserve(so, sndcc, rcvcc) { if (sbreserve(&so->so_snd, sndcc) == 0) goto bad; if (sbreserve(&so->so_rcv, rcvcc) == 0) goto bad2; if (so->so_rcv.sb_lowat == 0) so->so_rcv.sb_lowat = 1; if (so->so_snd.sb_lowat == 0) so->so_snd.sb_lowat = MCLBYTES; if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat) so->so_snd.sb_lowat = so->so_snd.sb_hiwat; return (0); [..] sbreserve() also clips: sbreserve(sb, cc) { [..] sb->sb_hiwat = cc; sb->sb_mbmax = min(cc * sb_efficiency, sb_max); if (sb->sb_lowat > sb->sb_hiwat) sb->sb_lowat = sb->sb_hiwat; return (1); [..] It seems to me that SO_SNDLOWAT = 0 is an error.. Depending on the timing of the setsockopt() calls relative to when soreserve() has been called, a value of zero is set to MCLBYTES or left at zero. I suspect the reason that there is no parameter checking at set time is so that the sanity checking is done after _all_ the parameters are set.. Otherwise, doing a series of setsockopt()'s could be a bit hairy if all combinations along the way were sanity checked. For example, if lowat is 1 and hiwat is 1024, and you wanted to change it to 2048/8192, under the present system setting lowat to 2048 first then hiwat next would work, but checking lowat > hiwat along the way would leave you with 1/8192 as a result which is not what would be expected. I guess the question is, when is soreserve() called to do the sanity check? Does this mean that soreserve() is being missed somewhere along the way and allowing nonsensical hi/low values to be used on a different size buffer? Cheers, -Peter
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199706221530.IAA06836>