From owner-freebsd-sparc64@FreeBSD.ORG Wed Mar 2 05:29:34 2005 Return-Path: Delivered-To: freebsd-sparc64@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BA2CE16A4CE for ; Wed, 2 Mar 2005 05:29:34 +0000 (GMT) Received: from carver.gumbysoft.com (carver.gumbysoft.com [66.220.23.50]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8CAC443D1F for ; Wed, 2 Mar 2005 05:29:34 +0000 (GMT) (envelope-from dwhite@gumbysoft.com) Received: by carver.gumbysoft.com (Postfix, from userid 1000) id 55D5D72DD5; Tue, 1 Mar 2005 21:29:34 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by carver.gumbysoft.com (Postfix) with ESMTP id 5350772DD4 for ; Tue, 1 Mar 2005 21:29:34 -0800 (PST) Date: Tue, 1 Mar 2005 21:29:34 -0800 (PST) From: Doug White To: freebsd-sparc64@freebsd.org Message-ID: <20050301211852.C73061@carver.gumbysoft.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Subject: Deadlock fix candidate X-BeenThere: freebsd-sparc64@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Porting FreeBSD to the Sparc List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Mar 2005 05:29:34 -0000 Hey folks, After consultation with alc and rwatson and (limited) testing by kris, I've come up the following patch as a fix for the sparc64 deadlocks that afflict the package cluster sparc boxes. Its an exact copy of what alc suggested (thanks :) ) and by assembly inspection generates the desired code. Originally I was going to redo the loop to be more like ipi_wait() with the declared volatile pointer, but a cast does the job. :) I'm trying to determine if this also fixes similar deadlocks/hangs on i386 and amd64. I haven't seen any assembly level changes with the patch on amd64, but I'm trying again on a fresh source tree in case I have pollution from test patches that cvsup hasn't caught. I can only reproduce the hang on amd64, but adding any sort of debugging makes it go away. Comments appreciated. If things look good I'll look to commit this tomorrow evening unless events dictate otherwise. Thanks! (Patch also available at http://people.freebsd.org/~dwhite/uipc_mbuf.c.20050301.patch) Index: uipc_mbuf.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_mbuf.c,v retrieving revision 1.143 diff -u -r1.143 uipc_mbuf.c --- uipc_mbuf.c 24 Feb 2005 00:40:33 -0000 1.143 +++ uipc_mbuf.c 1 Mar 2005 19:27:24 -0000 @@ -234,9 +234,12 @@ * This is tricky. We need to make sure to decrement the * refcount in a safe way but to also clean up if we're the * last reference. This method seems to do it without race. + * The volatile cast is required to emit the proper load + * instructions. Otherwise gcc will optimize the read outside + * of the while loop. */ while (dofree == 0) { - cnt = *(m->m_ext.ref_cnt); + cnt = *(volatile u_int *)(m->m_ext.ref_cnt); if (atomic_cmpset_int(m->m_ext.ref_cnt, cnt, cnt - 1)) { if (cnt == 1) dofree = 1; -- Doug White | FreeBSD: The Power to Serve dwhite@gumbysoft.com | www.FreeBSD.org