cvs commit: src/sys/kern subr_sleepqueue.c

John Baldwin jhb at FreeBSD.org
Fri Jan 25 11:44:51 PST 2008


jhb         2008-01-25 19:44:46 UTC

  FreeBSD src repository

  Modified files:
    sys/kern             subr_sleepqueue.c 
  Log:
  Fix a bug where a thread that hit the race where the sleep timeout fires
  while the thread does not hold the thread lock would stop blocking for
  subsequent interruptible sleeps and would always immediately fail the
  sleep with EWOULDBLOCK instead (even sleeps that didn't have a timeout).
  
  Some background:
  - KSE has a facility for allowing one thread to interrupt another thread.
    During this process, the target thread aborts any interruptible sleeps
    much as if the target thread had a pending signal.  Once the target
    thread acknowledges the interrupt, normal sleep handling resumes.  KSE
    manages this via the TDF_INTERRUPTED flag.  Specifically, it sets the
    flag when it sends an interrupt to another thread and clears it when
    the interrupt is acknowledged.  (Note that this is purely a software
    interrupt sort of thing and has no relation to hardware interrupts
    or kernel interrupt threads.)
  - The old code for handling the sleep timeout race handled the race
    by setting the TDF_INTERRUPT flag and faking a KSE-style thread
    interrupt to the thread in the process of going to sleep.  It probably
    should have just checked the TDF_TIMEOUT flag in sleepq_catch_signals()
    instead.
  - The bug was that the sleepq code would set TDF_INTERRUPT but it was
    never cleared.  The sleepq code couldn't safely clear it in case there
    actually was a real KSE thread interrupt pending for the target thread
    (in fact, the sleepq timeout actually stomped on said pending interrupt).
    Thus, any future interruptible sleeps (*sleep(.. PCATCH ..) or
    cv_*wait_sig()) would see the TDF_INTERRUPT flag set and immediately
    fail with EWOULDBLOCK.  The flag could be cleared if the thread belonged
    to a KSE process and another thread posted an interrupt to the original
    thread.  However, in the more common case of a non-KSE process, the
    thread would pretty much stop sleeping.
  - Fix the bug by just setting TDF_TIMEOUT in the sleepq timeout code and
    not messing with TDF_INTERRUPT and td_intrval.  With yesterday's fix to
    fix sleepq_switch() to check TDF_TIMEOUT, this is now sufficient.
  
  MFC after:      3 days
  
  Revision  Changes    Path
  1.43      +1 -2      src/sys/kern/subr_sleepqueue.c


More information about the cvs-src mailing list