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>
