--- /usr/src/sys/kern/kern_rwlock.c	2007-07-21 21:31:01.000000000 +0200
+++ kern/kern_rwlock.c	2007-09-22 23:03:37.000000000 +0200
@@ -284,6 +284,32 @@
 			continue;
 		}
 
+#ifdef ADAPTIVE_RWLOCKS
+		/*
+		 * If the owner is running on another CPU, spin until
+		 * the owner stops running or the state of the lock
+		 * changes.
+		 */
+		else {
+			x = RW_OWNER(x);
+			owner = (struct thread *)x;
+			if (TD_IS_RUNNING(owner)) {
+				if (LOCK_LOG_TEST(&rw->lock_object, 0))
+					CTR3(KTR_LOCK,
+					    "%s: spinning on %p held by %p",
+					    __func__, rw, owner);
+#ifdef LOCK_PROFILING_SHARED
+				lock_profile_obtain_lock_failed(
+				    &rw->lock_object, &contested, &waittime);
+#endif
+				while (RW_OWNER(rw->rw_lock) == x &&
+				    TD_IS_RUNNING(owner))
+					cpu_spinwait();
+				continue;
+			}
+		}
+#endif
+
 		/*
 		 * Okay, now it's the hard case.  Some other thread already
 		 * has a write lock, so acquire the turnstile lock so we can
@@ -303,6 +329,19 @@
 			continue;
 		}
 
+#ifdef ADAPTIVE_RWLOCKS
+		/*
+		 * If the owner is running on another CPU, skip the loop
+		 * and try to do adaptive spinning at the next try.
+		 */
+		owner = (struct thread *)RW_OWNER(x);
+		if (TD_IS_RUNNING(owner)) {
+			turnstile_cancel(ts);
+			cpu_spinwait();
+			continue;
+		}
+#endif
+
 		/*
 		 * Ok, it's still a write lock.  If the RW_LOCK_READ_WAITERS
 		 * flag is already set, then we can go ahead and block.  If
@@ -321,29 +360,6 @@
 				    __func__, rw);
 		}
 
-#ifdef ADAPTIVE_RWLOCKS
-		/*
-		 * If the owner is running on another CPU, spin until
-		 * the owner stops running or the state of the lock
-		 * changes.
-		 */
-		owner = (struct thread *)RW_OWNER(x);
-		if (TD_IS_RUNNING(owner)) {
-			turnstile_cancel(ts);
-			if (LOCK_LOG_TEST(&rw->lock_object, 0))
-				CTR3(KTR_LOCK, "%s: spinning on %p held by %p",
-				    __func__, rw, owner);
-#ifdef LOCK_PROFILING_SHARED
-			lock_profile_obtain_lock_failed(&rw->lock_object,
-			    &contested, &waittime);
-#endif
-			while ((struct thread*)RW_OWNER(rw->rw_lock)== owner &&
-			    TD_IS_RUNNING(owner))
-				cpu_spinwait();
-			continue;
-		}
-#endif
-
 		/*
 		 * We were unable to acquire the lock and the read waiters
 		 * flag is set, so we must block on the turnstile.
@@ -526,6 +542,31 @@
 		    rw->lock_object.lo_name, (void *)rw->rw_lock, file, line);
 
 	while (!_rw_write_lock(rw, tid)) {
+#ifdef ADAPTIVE_RWLOCKS
+		/*
+		 * If the owner is running on another CPU, spin until
+		 * the owner stops running or the state of the lock
+		 * changes.
+		 */
+		v = rw->rw_lock;
+		if (!(v & RW_LOCK_READ)) {
+			v = RW_OWNER(v);
+			owner = (struct thread *)v;
+			if (TD_IS_RUNNING(owner)) {
+				if (LOCK_LOG_TEST(&rw->lock_object, 0))
+					CTR3(KTR_LOCK,
+					    "%s: spinning on %p held by %p",
+					    __func__, rw, owner);
+				lock_profile_obtain_lock_failed(
+				    &rw->lock_object, &contested, &waittime);
+				while (RW_OWNER(rw->rw_lock) == v &&
+				    TD_IS_RUNNING(owner))
+					cpu_spinwait();
+				continue;
+			}
+		}
+#endif
+
 		ts = turnstile_trywait(&rw->lock_object);
 		v = rw->rw_lock;
 
@@ -539,6 +580,19 @@
 			continue;
 		}
 
+#ifdef ADAPTIVE_RWLOCKS
+		/*
+		 * If the owner is running on another CPU, skip the loop
+		 * and try to do adaptive spinning at the next try.
+		 */
+		owner = (struct thread *)RW_OWNER(v);
+		if (TD_IS_RUNNING(owner)) {
+			turnstile_cancel(ts);
+			cpu_spinwait();
+			continue;
+		}
+#endif
+
 		/*
 		 * If the lock was released by a writer with both readers
 		 * and writers waiting and a reader hasn't woken up and
@@ -580,27 +634,6 @@
 				    __func__, rw);
 		}
 
-#ifdef ADAPTIVE_RWLOCKS
-		/*
-		 * If the lock is write locked and the owner is
-		 * running on another CPU, spin until the owner stops
-		 * running or the state of the lock changes.
-		 */
-		owner = (struct thread *)RW_OWNER(v);
-		if (!(v & RW_LOCK_READ) && TD_IS_RUNNING(owner)) {
-			turnstile_cancel(ts);
-			if (LOCK_LOG_TEST(&rw->lock_object, 0))
-				CTR3(KTR_LOCK, "%s: spinning on %p held by %p",
-				    __func__, rw, owner);
-			lock_profile_obtain_lock_failed(&rw->lock_object,
-			    &contested, &waittime);
-			while ((struct thread*)RW_OWNER(rw->rw_lock)== owner &&
-			    TD_IS_RUNNING(owner))
-				cpu_spinwait();
-			continue;
-		}
-#endif
-
 		/*
 		 * We were unable to acquire the lock and the write waiters
 		 * flag is set, so we must block on the turnstile.
