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