git: kernel - Fix rare missed wakeup() in lockmgr
Matthew Dillon
dillon at crater.dragonflybsd.org
Wed Feb 14 11:55:09 PST 2018
commit 8319957b9f679319761213e5c0e28293afd26e34
Author: Matthew Dillon <dillon at apollo.backplane.com>
Date: Wed Feb 14 11:49:40 2018 -0800
kernel - Fix rare missed wakeup() in lockmgr
* Fix a rare missed wakeup() case in lockmgr. lk_count can briefly
become (SHARED | 0 counts | (EXREQ or UPREQ)). Three competing cores
can then cause a situation where undo_shreq() fails to issue a wakeup()
to threads acquiring a shared lock that are blocked waiting for the
EXREQ or UPREQ
Issue the missing wakeup() for this case.
* This race arises because of an optimization we make when dropping a
shared lock. atomic_fcmpset*() loops are fairly poor at dealing
with concurrent increments and decrements, so undo_shreq() (which
is also used when releasing a standard shared lock) decrements the
shared lock count first, then deals with EXREQ or UPREQ afterwords.
Usually a shared lock request bumps the shared lock count before
blocking, which other lock releases use to determine the need for a
wakeup(). However, shared lock requests cannot bump the shared lock
count when the lock is already held SHARED but there is an EXREQ or
UPREQ pending, because doing do basically grants the shared lock
immediately.
This combination leads to the brief situation which allows other cpu
cores to squeeze in operations of their own without realizing that
someone might be blocked trying to obtain a shared lock, but with no
shared count present to indicate so. If the undo_shreq()'s later
atomic_fcmpset*() calls then fail, or find that there is no EXREQ or
UPREQ pending, it fails to issue the needed wakeup().
Summary of changes:
sys/kern/kern_lock.c | 10 ++++++++++
1 file changed, 10 insertions(+)
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/8319957b9f679319761213e5c0e28293afd26e34
--
DragonFly BSD source repository
More information about the Commits
mailing list