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
This commit is contained in:
Mateusz Guzik 2017-03-01 05:06:21 +00:00
parent 26e8791990
commit a21018063b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=314474
3 changed files with 3 additions and 3 deletions

View File

@ -1151,7 +1151,7 @@ __rw_try_upgrade(volatile uintptr_t *c, const char *file, int line)
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;

View File

@ -410,7 +410,7 @@ sx_try_upgrade_(struct sx *sx, const char *file, int line)
* 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) {

View File

@ -185,7 +185,7 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
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) \