Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Jan 2011 07:39:54 -0800
From:      mdf@FreeBSD.org
To:        Lawrence Stewart <lstewart@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r217748 - head/sys/netinet/cc
Message-ID:  <AANLkTi=jc3VV1Sf6QsKQHCnnLVpL7%2B3K0qBgwdR60F%2Bp@mail.gmail.com>
In-Reply-To: <201101231300.p0ND0PZi055936@svn.freebsd.org>
References:  <201101231300.p0ND0PZi055936@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
For sbuf use for a sysctl you can use sbuf_init_for_sysctl() which
will, instead of growing, push the current data out using SYSCTL_OUT
to a wired user buffer.  There's a few examples in the vm/ code.  This
can sometimes significantly simplify the code since there's no need to
worry about held mutex/rwlock anymore.

Thanks,
matthew

On Sun, Jan 23, 2011 at 5:00 AM, Lawrence Stewart <lstewart@freebsd.org> wr=
ote:
> Author: lstewart
> Date: Sun Jan 23 13:00:25 2011
> New Revision: 217748
> URL: http://svn.freebsd.org/changeset/base/217748
>
> Log:
> =A0An sbuf configured with SBUF_AUTOEXTEND will call malloc with M_WAITOK=
 when a
> =A0write to the buffer causes it to overflow. We therefore can't hold the=
 CC list
> =A0rwlock over a call to sbuf_printf() for an sbuf configured with SBUF_A=
UTOEXTEND.
>
> =A0Switch to a fixed length sbuf which should be of sufficient size excep=
t in the
> =A0very unlikely event that the sysctl is being processed as one or more =
new
> =A0algorithms are loaded. If that happens, we accept the race and may fai=
l the
> =A0sysctl gracefully if there is insufficient room to print the names of =
all the
> =A0algorithms.
>
> =A0This should address a WITNESS warning and the potential panic that wou=
ld occur
> =A0if the sbuf call to malloc did sleep whilst holding the CC list rwlock=
.
>
> =A0Sponsored by: FreeBSD Foundation
> =A0Reported by: =A0Nick Hibma
> =A0Reviewed by: =A0bz
> =A0MFC after: =A0 =A03 weeks
> =A0X-MFC with: =A0 r215166
>
> Modified:
> =A0head/sys/netinet/cc/cc.c
>
> Modified: head/sys/netinet/cc/cc.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/sys/netinet/cc/cc.c =A0 =A0Sun Jan 23 12:44:17 2011 =A0 =A0 =A0 =
=A0(r217747)
> +++ head/sys/netinet/cc/cc.c =A0 =A0Sun Jan 23 13:00:25 2011 =A0 =A0 =A0 =
=A0(r217748)
> @@ -128,20 +128,37 @@ cc_list_available(SYSCTL_HANDLER_ARGS)
> =A0{
> =A0 =A0 =A0 =A0struct cc_algo *algo;
> =A0 =A0 =A0 =A0struct sbuf *s;
> - =A0 =A0 =A0 int err, first;
> + =A0 =A0 =A0 int err, first, nalgos;
>
> - =A0 =A0 =A0 err =3D 0;
> + =A0 =A0 =A0 err =3D nalgos =3D 0;
> =A0 =A0 =A0 =A0first =3D 1;
> - =A0 =A0 =A0 s =3D sbuf_new(NULL, NULL, TCP_CA_NAME_MAX, SBUF_AUTOEXTEND=
);
> +
> + =A0 =A0 =A0 CC_LIST_RLOCK();
> + =A0 =A0 =A0 STAILQ_FOREACH(algo, &cc_list, entries) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 nalgos++;
> + =A0 =A0 =A0 }
> + =A0 =A0 =A0 CC_LIST_RUNLOCK();
> +
> + =A0 =A0 =A0 s =3D sbuf_new(NULL, NULL, nalgos * TCP_CA_NAME_MAX, SBUF_F=
IXEDLEN);
>
> =A0 =A0 =A0 =A0if (s =3D=3D NULL)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return (ENOMEM);
>
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* It is theoretically possible for the CC list to have g=
rown in size
> + =A0 =A0 =A0 =A0* since the call to sbuf_new() and therefore for the sbu=
f to be too
> + =A0 =A0 =A0 =A0* small. If this were to happen (incredibly unlikely), t=
he sbuf will
> + =A0 =A0 =A0 =A0* reach an overflow condition, sbuf_printf() will return=
 an error and
> + =A0 =A0 =A0 =A0* the sysctl will fail gracefully.
> + =A0 =A0 =A0 =A0*/
> =A0 =A0 =A0 =A0CC_LIST_RLOCK();
> =A0 =A0 =A0 =A0STAILQ_FOREACH(algo, &cc_list, entries) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0err =3D sbuf_printf(s, first ? "%s" : ", %=
s", algo->name);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (err)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (err) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Sbuf overflow condition.=
 */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 err =3D EOVERFLOW;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0first =3D 0;
> =A0 =A0 =A0 =A0}
> =A0 =A0 =A0 =A0CC_LIST_RUNLOCK();
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTi=jc3VV1Sf6QsKQHCnnLVpL7%2B3K0qBgwdR60F%2Bp>