From owner-freebsd-current@FreeBSD.ORG Mon Oct 11 11:37:29 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 08FE516A4CE for ; Mon, 11 Oct 2004 11:37:29 +0000 (GMT) Received: from mproxy.gmail.com (rproxy.gmail.com [64.233.170.207]) by mx1.FreeBSD.org (Postfix) with ESMTP id A278A43D58 for ; Mon, 11 Oct 2004 11:37:28 +0000 (GMT) (envelope-from marchenko@gmail.com) Received: by mproxy.gmail.com with SMTP id 76so241497rnk for ; Mon, 11 Oct 2004 04:37:25 -0700 (PDT) Received: by 10.38.181.6 with SMTP id d6mr1250774rnf; Mon, 11 Oct 2004 04:37:24 -0700 (PDT) Received: by 10.38.22.66 with HTTP; Mon, 11 Oct 2004 04:37:24 -0700 (PDT) Message-ID: Date: Mon, 11 Oct 2004 07:37:24 -0400 From: Vlad To: Robert Watson In-Reply-To: Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit References: <20041010124058.58a03dba.ubm@u-boot-man.de> cc: current@freebsd.org cc: Marc UBM Bocklet Subject: Re: [BETA7-panic] sodealloc(): so_count 1 X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Vlad List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Oct 2004 11:37:29 -0000 Robert, this patch is a replacement (not addition) to what Brian came up with before here http://green.homeunix.org/~green/tcp_accept_race_crash.patch correct? I see they patch different files, so just making sure thank you guys for your work and patience with the problem :) On Mon, 11 Oct 2004 04:13:15 -0400 (EDT), Robert Watson wrote: > > On Sun, 10 Oct 2004, Marc UBM Bocklet wrote: > > > No, but I can revert the local patches, configure a dump device and try > > getting one tomorrow or the day after that. > > Marc, > > Afer a couple of days of experimenting and chatting, Brian and I have > developed what we hope is a less intrusive but fully functional fix for > this problem. I ran it through a barrage of tests yesterday, although I > couldn't reproduce the problem originally, and the system still appears to > run :-). I've committed the patch to CVS HEAD (6.x), and will merge to > 5.x in a few days, and assuming that your testing of the change doesn't > reveal that it didn't fix the problem. I have included a copy of the > patch committed (minus $FreeBSD$ change) below. > > If you could give this a spin, it would be much appreciated. Thanks for > your (and Vlad's) patience as we worked this out! (And many thanks to > Brian for doing so much of the work to fix it). > > Robert N M Watson FreeBSD Core Team, TrustedBSD Projects > robert@fledge.watson.org Principal Research Scientist, McAfee Research > > > Index: uipc_socket.c > =================================================================== > RCS file: /home/ncvs/src/sys/kern/uipc_socket.c,v > retrieving revision 1.212 > retrieving revision 1.213 > diff -u -r1.212 -r1.213 > --- uipc_socket.c 5 Sep 2004 14:33:21 -0000 1.212 > +++ uipc_socket.c 11 Oct 2004 08:11:26 -0000 1.213 > @@ -316,22 +316,34 @@ > return (0); > } > > +/* > + * Attempt to free a socket. This should really be sotryfree(). > + * > + * We free the socket if the protocol is no longer interested in the socket, > + * there's no file descriptor reference, and the refcount is 0. While the > + * calling macro sotryfree() tests the refcount, sofree() has to test it > + * again as it's possible to race with an accept()ing thread if the socket is > + * in an listen queue of a listen socket, as being in the listen queue > + * doesn't elevate the reference count. sofree() acquires the accept mutex > + * early for this test in order to avoid that race. > + */ > void > sofree(so) > struct socket *so; > { > struct socket *head; > > - KASSERT(so->so_count == 0, ("socket %p so_count not 0", so)); > - SOCK_LOCK_ASSERT(so); > + SOCK_UNLOCK(so); > + ACCEPT_LOCK(); > + SOCK_LOCK(so); > > - if (so->so_pcb != NULL || (so->so_state & SS_NOFDREF) == 0) { > + if (so->so_pcb != NULL || (so->so_state & SS_NOFDREF) == 0 || > + so->so_count != 0) { > SOCK_UNLOCK(so); > + ACCEPT_UNLOCK(); > return; > } > > - SOCK_UNLOCK(so); > - ACCEPT_LOCK(); > head = so->so_head; > if (head != NULL) { > KASSERT((so->so_qstate & SQ_COMP) != 0 || > @@ -353,6 +365,7 @@ > * the listening socket is closed. > */ > if ((so->so_qstate & SQ_COMP) != 0) { > + SOCK_UNLOCK(so); > ACCEPT_UNLOCK(); > return; > } > @@ -365,6 +378,7 @@ > (so->so_qstate & SQ_INCOMP) == 0, > ("sofree: so_head == NULL, but still SQ_COMP(%d) or SQ_INCOMP(%d)", > so->so_qstate & SQ_COMP, so->so_qstate & SQ_INCOMP)); > + SOCK_UNLOCK(so); > ACCEPT_UNLOCK(); > SOCKBUF_LOCK(&so->so_snd); > so->so_snd.sb_flags |= SB_NOINTR; > > > > > _______________________________________________ > freebsd-current@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-current > To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org" > -- Vlad