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;
 }
 

Reply via email to