Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Jul 2009 01:23:24 -0400
From:      Randall Stewart <rrs@lakerest.net>
To:        Pawel Jakub Dawidek <pjd@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:  <354E0657-DC37-4493-8E17-D09B257B5A28@lakerest.net>
In-Reply-To: <20090729051016.GB3550@garage.freebsd.pl>
References:  <200907281409.n6SE971u034585@svn.freebsd.org> <20090729051016.GB3550@garage.freebsd.pl>

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

On Jul 29, 2009, at 1:10 AM, Pawel Jakub Dawidek wrote:

> 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
>>
>> 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.
>>
>>  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.
>>
>>  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 == 0)
>
> It would be a bit cleaner to compare with SCTP_READ_LOCK_NOT_HELD  
> here,
> instead of 0.

I suppose so ;-)


>
>> +		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 = prev;
>> 	} else {
>> 		/* Everything got collapsed out?? */
>> -		SCTP_INP_READ_UNLOCK(inp);
>> +		if (inp_read_lock_held == 0)
>> +			SCTP_INP_READ_UNLOCK(inp);
>> 		return;
>> 	}
>> 	if (end) {
>> 		control->end_added = 1;
>> 	}
>> 	TAILQ_INSERT_TAIL(&inp->read_queue, control, next);
>> -	SCTP_INP_READ_UNLOCK(inp);
>> +	if (inp_read_lock_held == 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?

Hmm... I suppose one could go that way... but traditionally upper code  
as
told the lower code that it holds/does not hold the lock. This is true
in quite a few other functions...

R

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

------------------------------
Randall Stewart
803-317-4952 (cell)
803-345-0391(direct)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?354E0657-DC37-4493-8E17-D09B257B5A28>