Module Name: src Committed By: ad Date: Fri Apr 24 17:53:06 UTC 2009
Modified Files: src/sys/kern: kern_rwlock.c Log Message: A workaround for a bug with some Opteron revisions where locked operations sometimes do not serve as memory barriers, allowing memory references to bleed outside of critical sections. It's possible that this is the reason for pkgbuild's longstanding crashiness. For rwlocks, always enable the explicit membars. They were disabled only on x86, and since they are not in the fast-path it's not a big deal. TODO: convert these to an atomic_membar_foo() or similar that does ordering between regular data references and atomic references. To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/sys/kern/kern_rwlock.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_rwlock.c diff -u src/sys/kern/kern_rwlock.c:1.29 src/sys/kern/kern_rwlock.c:1.30 --- src/sys/kern/kern_rwlock.c:1.29 Sun Apr 19 08:36:04 2009 +++ src/sys/kern/kern_rwlock.c Fri Apr 24 17:53:06 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_rwlock.c,v 1.29 2009/04/19 08:36:04 ad Exp $ */ +/* $NetBSD: kern_rwlock.c,v 1.30 2009/04/24 17:53:06 ad Exp $ */ /*- * Copyright (c) 2002, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.29 2009/04/19 08:36:04 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.30 2009/04/24 17:53:06 ad Exp $"); #define __RWLOCK_PRIVATE @@ -341,9 +341,7 @@ ~RW_WRITE_WANTED); if (__predict_true(next == owner)) { /* Got it! */ -#ifndef __HAVE_ATOMIC_AS_MEMBAR membar_enter(); -#endif break; } @@ -465,9 +463,7 @@ * proceed to do direct handoff if there are waiters, and if the * lock would become unowned. */ -#ifndef __HAVE_ATOMIC_AS_MEMBAR membar_exit(); -#endif for (;;) { new = (owner - decr); if ((new & (RW_THREAD | RW_HAS_WAITERS)) == RW_HAS_WAITERS) @@ -567,13 +563,11 @@ next = rw_cas(rw, owner, owner + incr); if (__predict_true(next == owner)) { /* Got it! */ + membar_enter(); break; } } -#ifndef __HAVE_ATOMIC_AS_MEMBAR - membar_enter(); -#endif RW_WANTLOCK(rw, op, true); RW_LOCKED(rw, op); RW_DASSERT(rw, (op != RW_READER && RW_OWNER(rw) == curthread) || @@ -600,10 +594,7 @@ RW_ASSERT(rw, RW_OWNER(rw) == curthread); RW_UNLOCKED(rw, RW_WRITER); -#ifndef __HAVE_ATOMIC_AS_MEMBAR membar_producer(); -#endif - owner = rw->rw_owner; if ((owner & RW_HAS_WAITERS) == 0) { /* @@ -697,8 +688,10 @@ } new = curthread | RW_WRITE_LOCKED | (owner & ~RW_THREAD); next = rw_cas(rw, owner, new); - if (__predict_true(next == owner)) + if (__predict_true(next == owner)) { + membar_producer(); break; + } } RW_UNLOCKED(rw, RW_READER); @@ -706,10 +699,6 @@ RW_DASSERT(rw, rw->rw_owner & RW_WRITE_LOCKED); RW_DASSERT(rw, RW_OWNER(rw) == curthread); -#ifndef __HAVE_ATOMIC_AS_MEMBAR - membar_producer(); -#endif - return 1; }