Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Jul 2003 04:06:40 -0700 (PDT)
From:      Mike Makonnen <mtm@FreeBSD.org>
To:        src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   cvs commit: src/sys/kern kern_umtx.c src/sys/sys proc.h
Message-ID:  <200307171106.h6HB6emd076862@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
mtm         2003/07/17 04:06:40 PDT

  FreeBSD src repository

  Modified files:
    sys/kern             kern_umtx.c 
    sys/sys              proc.h 
  Log:
  Fix umtx locking, for libthr, in the kernel.
  1. There was a race condition between a thread unlocking
     a umtx and the thread contesting it. If the unlocking
     thread won the race it may try to wakeup a thread that
     was not yet in msleep(). The contesting thread would then
     go to sleep to await a wakeup that would never come. It's
     not possible to close the race by using a lock because
     calls to casuptr() may have to fault a page in from swap.
     Instead, the race was closed by introducing a flag that
     the unlocking thread will set when waking up a thread.
     The contesting thread will check for this flag before
     going to sleep. For now the flag is kept in td_flags,
     but it may be better to use some other member or create
     a new one because of the possible performance/contention
     issues of having to own sched_lock. Thanks to jhb for
     pointing me in the right direction on this one.
  
  2. Once a umtx was contested all future locks and unlocks
     were happening in the kernel, regardless of whether it
     was contested or not. To prevent this from happening,
     when a thread locks a umtx it checks the queue for that
     umtx and unsets the contested bit if there are no other
     threads waiting on it. Again, this is slightly more
     complicated than it needs to be because we can't hold
     a lock across casuptr(). So, the thread has to check
     the queue again after unseting the bit, and reset the
     contested bit if it finds that another thread has put
     itself on the queue in the mean time.
  
  3. Remove the if... block for unlocking an uncontested
     umtx, and replace it with a KASSERT. The _only_ time
     a thread should be unlocking a umtx in the kernel is
     if it is contested.
  
  Revision  Changes    Path
  1.8       +47 -24    src/sys/kern/kern_umtx.c
  1.341     +1 -0      src/sys/sys/proc.h



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200307171106.h6HB6emd076862>