Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Nov 2005 16:06:05 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   cvs commit: src/sys/kern uipc_usrreq.c
Message-ID:  <200511101606.jAAG65SX095272@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
rwatson     2005-11-10 16:06:05 UTC

  FreeBSD src repository

  Modified files:
    sys/kern             uipc_usrreq.c 
  Log:
  Correct a number of serious and closely related bugs in the UNIX domain
  socket file descriptor garbage collection code, which is intended to
  detect and clear cycles of orphaned file descriptors that are "in-flight"
  in a socket when that socket is closed before they are received.  The
  algorithm present was both run at poor times (resulting in recursion and
  reentrance), and also buggy in the presence of parallelism.  In order to
  fix these problems, make the following changes:
  
  - When there are in-flight sockets and a UNIX domain socket is destroyed,
    asynchronously schedule the garbage collector, rather than running it
    synchronously in the current context.  This avoids lock order issues
    when the garbage collection code reenters the UNIX domain socket code,
    avoiding lock order reversals, deadlocks, etc.  Run the code
    asynchronously in a task queue.
  
  - In the garbage collector, when skipping file descriptors that have
    entered a closing state (i.e., have f_count == 0), re-test the FDEFER
    flag, and decrement unp_defer.  As file descriptors can now transition
    to a closed state, while the garbage collector is running, it is no
    longer the case that unp_defer will remain an accurate count of
    deferred sockets in the mark portion of the GC algorithm.  Otherwise,
    the garbage collector will loop waiting waiting for unp_defer to reach
    zero, which it will never do as it is skipping file descriptors that
    were marked in an earlier pass, but now closed.
  
  - Acquire the UNIX domain socket subsystem lock in unp_discard() when
    modifying the unp_rights counter, or a read/write race is risked with
    other threads also manipulating the counter.
  
  While here:
  
  - Remove #if 0'd code regarding acquiring the socket buffer sleep lock in
    the garbage collector, this is not required as we are able to use the
    socket buffer receive lock to protect scanning the receive buffer for
    in-flight file descriptors on the socket buffer.
  
  - Annotate that the description of the garbage collector implementation
    is increasingly inaccurate and needs to be updated.
  
  - Add counters of the number of deferred garbage collections and recycled
    file descriptors.  This will be removed and is here temporarily for
    debugging purposes.
  
  With these changes in place, the unp_passfd regression test now appears
  to be passed consistently on UP and SMP systems for extended runs,
  whereas before it hung quickly or panicked, depending on which bug was
  triggered.
  
  Reported by:    Philip Kizer <pckizer at nostrum dot com>
  MFC after:      2 weeks
  
  Revision  Changes    Path
  1.159     +45 -50    src/sys/kern/uipc_usrreq.c



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