svn commit: r314474 - in head/sys: kern sys

Mateusz Guzik mjg at FreeBSD.org
Wed Mar 1 05:06:24 UTC 2017


Author: mjg
Date: Wed Mar  1 05:06:21 2017
New Revision: 314474
URL: https://svnweb.freebsd.org/changeset/base/314474

Log:
  locks: ensure proper barriers are used with atomic ops when necessary
  
  Unclear how, but the locking routine for mutexes was using the *release*
  barrier instead of acquire. This must have been either a copy-pasto or bad
  completion.
  
  Going through other uses of atomics shows no barriers in:
  - upgrade routines (addressed in this patch)
  - sections protected with turnstile locks - this should be fine as necessary
    barriers are in the worst case provided by turnstile unlock
  
  I would like to thank Mark Millard and andreast@ for reporting the problem and
  testing previous patches before the issue got identified.
  
  ps.
    .-'---`-.
  ,'          `.
  |             \
  |              \
  \           _  \
  ,\  _    ,'-,/-)\
  ( * \ \,' ,' ,'-)
   `._,)     -',-')
     \/         ''/
      )        / /
     /       ,'-'
  
  Hardware provided by: IBM LTC

Modified:
  head/sys/kern/kern_rwlock.c
  head/sys/kern/kern_sx.c
  head/sys/sys/mutex.h

Modified: head/sys/kern/kern_rwlock.c
==============================================================================
--- head/sys/kern/kern_rwlock.c	Wed Mar  1 05:05:05 2017	(r314473)
+++ head/sys/kern/kern_rwlock.c	Wed Mar  1 05:06:21 2017	(r314474)
@@ -1151,7 +1151,7 @@ __rw_try_upgrade(volatile uintptr_t *c, 
 		if (RW_READERS(v) > 1)
 			break;
 		if (!(v & RW_LOCK_WAITERS)) {
-			success = atomic_cmpset_ptr(&rw->rw_lock, v, tid);
+			success = atomic_cmpset_acq_ptr(&rw->rw_lock, v, tid);
 			if (!success)
 				continue;
 			break;

Modified: head/sys/kern/kern_sx.c
==============================================================================
--- head/sys/kern/kern_sx.c	Wed Mar  1 05:05:05 2017	(r314473)
+++ head/sys/kern/kern_sx.c	Wed Mar  1 05:06:21 2017	(r314474)
@@ -410,7 +410,7 @@ sx_try_upgrade_(struct sx *sx, const cha
 	 * we will wake up the exclusive waiters when we drop the lock.
 	 */
 	x = sx->sx_lock & SX_LOCK_EXCLUSIVE_WAITERS;
-	success = atomic_cmpset_ptr(&sx->sx_lock, SX_SHARERS_LOCK(1) | x,
+	success = atomic_cmpset_acq_ptr(&sx->sx_lock, SX_SHARERS_LOCK(1) | x,
 	    (uintptr_t)curthread | x);
 	LOCK_LOG_TRY("XUPGRADE", &sx->lock_object, 0, success, file, line);
 	if (success) {

Modified: head/sys/sys/mutex.h
==============================================================================
--- head/sys/sys/mutex.h	Wed Mar  1 05:05:05 2017	(r314473)
+++ head/sys/sys/mutex.h	Wed Mar  1 05:06:21 2017	(r314474)
@@ -185,7 +185,7 @@ void	thread_lock_flags_(struct thread *,
 	atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid))
 
 #define _mtx_obtain_lock_fetch(mp, vp, tid)				\
-	atomic_fcmpset_rel_ptr(&(mp)->mtx_lock, vp, (tid))
+	atomic_fcmpset_acq_ptr(&(mp)->mtx_lock, vp, (tid))
 
 /* Try to release mtx_lock if it is unrecursed and uncontested. */
 #define _mtx_release_lock(mp, tid)					\


More information about the svn-src-all mailing list