Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Jul 2009 07:10:16 +0200
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        Randall Stewart <rrs@FreeBSD.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r195918 - head/sys/netinet
Message-ID:  <20090729051016.GB3550@garage.freebsd.pl>
In-Reply-To: <200907281409.n6SE971u034585@svn.freebsd.org>
References:  <200907281409.n6SE971u034585@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--yEPQxsgoJgBvi8ip
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Jul 28, 2009 at 02:09:07PM +0000, Randall Stewart wrote:
> Author: rrs
> Date: Tue Jul 28 14:09:06 2009
> New Revision: 195918
> URL: http://svn.freebsd.org/changeset/base/195918
>=20
> Log:
>   Turns out that when a receiver forwards through its TNS's the
>   processing code holds the read lock (when processing a
>   FWD-TSN for pr-sctp). If it finds stranded data that
>   can be given to the application, it calls sctp_add_to_readq().
>   The readq function also grabs this lock. So if INVAR is on
>   we get a double recurse on a non-recursive lock and panic.
>  =20
>   This fix will change it so that readq() function gets a
>   flag to tell if the lock is held, if so then it does not
>   get the lock.
>  =20
>   Approved by:	re@freebsd.org (Kostik Belousov)
>   MFC after:	1 week
[...]
>  	sctp_add_to_readq(stcb->sctp_ep, stcb, control,
> -	    &stcb->sctp_socket->so_rcv, 1, so_locked);
> +	    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
[...]
> @@ -4301,6 +4306,7 @@ sctp_add_to_readq(struct sctp_inpcb *inp
>      struct sctp_queued_to_read *control,
>      struct sockbuf *sb,
>      int end,
> +    int inp_read_lock_held,
>      int so_locked
>  #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
>      SCTP_UNUSED
> @@ -4321,7 +4327,8 @@ sctp_add_to_readq(struct sctp_inpcb *inp
>  #endif
>  		return;
>  	}
> -	SCTP_INP_READ_LOCK(inp);
> +	if (inp_read_lock_held =3D=3D 0)

It would be a bit cleaner to compare with SCTP_READ_LOCK_NOT_HELD here,
instead of 0.

> +		SCTP_INP_READ_LOCK(inp);
>  	if (!(control->spec_flags & M_NOTIFICATION)) {
>  		atomic_add_int(&inp->total_recvs, 1);
>  		if (!control->do_not_ref_stcb) {
> @@ -4362,14 +4369,16 @@ sctp_add_to_readq(struct sctp_inpcb *inp
>  		control->tail_mbuf =3D prev;
>  	} else {
>  		/* Everything got collapsed out?? */
> -		SCTP_INP_READ_UNLOCK(inp);
> +		if (inp_read_lock_held =3D=3D 0)
> +			SCTP_INP_READ_UNLOCK(inp);
>  		return;
>  	}
>  	if (end) {
>  		control->end_added =3D 1;
>  	}
>  	TAILQ_INSERT_TAIL(&inp->read_queue, control, next);
> -	SCTP_INP_READ_UNLOCK(inp);
> +	if (inp_read_lock_held =3D=3D 0)
> +		SCTP_INP_READ_UNLOCK(inp);
>  	if (inp && inp->sctp_socket) {
>  		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) {
>  			SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket);

Instead of using additional argument to the sctp_add_to_readq()
function, wouldn't it be sufficient to just check with mtx_owned(9) if
the lock is already held?

--=20
Pawel Jakub Dawidek                       http://www.wheel.pl
pjd@FreeBSD.org                           http://www.FreeBSD.org
FreeBSD committer                         Am I Evil? Yes, I Am!

--yEPQxsgoJgBvi8ip
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4 (FreeBSD)

iD8DBQFKb9m4ForvXbEpPzQRAh/FAJ0Uc/bklivoexP+BYV0cx6dFI69fwCgs6in
SiImPQCzfLDftrdDiobxcDg=
=W5Wi
-----END PGP SIGNATURE-----

--yEPQxsgoJgBvi8ip--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090729051016.GB3550>