cvs commit: src/sys/kern uipc_socket.c uipc_socket2.c uipc_syscalls.c src/sys/netgraph ng_ksocket.c src/sys/netgraph/bluetooth/socket ng_btsocket_rfcomm.c src/sys/sys socketvar.h

Robert Watson rwatson at FreeBSD.org
Tue Jun 1 21:15:41 PDT 2004


rwatson     2004/06/01 21:15:39 PDT

  FreeBSD src repository

  Modified files:
    sys/kern             uipc_socket.c uipc_socket2.c 
                         uipc_syscalls.c 
    sys/netgraph         ng_ksocket.c 
    sys/netgraph/bluetooth/socket ng_btsocket_rfcomm.c 
    sys/sys              socketvar.h 
  Log:
  Integrate accept locking from rwatson_netperf, introducing a new
  global mutex, accept_mtx, which serializes access to the following
  fields across all sockets:
  
            so_qlen          so_incqlen         so_qstate
            so_comp          so_incomp          so_list
            so_head
  
  While providing only coarse granularity, this approach avoids lock
  order issues between sockets by avoiding ownership of the fields
  by a specific socket and its per-socket mutexes.
  
  While here, rewrite soclose(), sofree(), soaccept(), and
  sonewconn() to add assertions, close additional races and  address
  lock order concerns.  In particular:
  
  - Reorganize the optimistic concurrency behavior in accept1() to
    always allocate a file descriptor with falloc() so that if we do
    find a socket, we don't have to encounter the "Oh, there wasn't
    a socket" race that can occur if falloc() sleeps in the current
    code, which broke inbound accept() ordering, not to mention
    requiring backing out socket state changes in a way that raced
    with the protocol level.  We may want to add a lockless read of
    the queue state if polling of empty queues proves to be important
    to optimize.
  
  - In accept1(), soref() the socket while holding the accept lock
    so that the socket cannot be free'd in a race with the protocol
    layer.  Likewise in netgraph equivilents of the accept1() code.
  
  - In sonewconn(), loop waiting for the queue to be small enough to
    insert our new socket once we've committed to inserting it, or
    races can occur that cause the incomplete socket queue to
    overfill.  In the previously implementation, it was sufficient
    to simply tested once since calling soabort() didn't release
    synchronization permitting another thread to insert a socket as
    we discard a previous one.
  
  - In soclose()/sofree()/et al, it is the responsibility of the
    caller to remove a socket from the incomplete connection queue
    before calling soabort(), which prevents soabort() from having
    to walk into the accept socket to release the socket from its
    queue, and avoids races when releasing the accept mutex to enter
    soabort(), permitting soabort() to avoid lock ordering issues
    with the caller.
  
  - Generally cluster accept queue related operations together
    throughout these functions in order to facilitate locking.
  
  Annotate new locking in socketvar.h.
  
  Revision  Changes    Path
  1.174     +49 -22    src/sys/kern/uipc_socket.c
  1.127     +45 -21    src/sys/kern/uipc_socket2.c
  1.186     +25 -43    src/sys/kern/uipc_syscalls.c
  1.8       +5 -4      src/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
  1.42      +10 -7     src/sys/netgraph/ng_ksocket.c
  1.114     +18 -8     src/sys/sys/socketvar.h


More information about the cvs-src mailing list