[FreeBSD6.1-RELEASE]problem about soisconnected() in
uipc_socket2.c
Robert Watson
rwatson at FreeBSD.org
Tue Jun 13 11:52:52 UTC 2006
On Tue, 13 Jun 2006, Blue wrote:
> I have found a questionable code in soisconnected() function in
> uipc_socket2.c. In the very beginning, the SOCK_LOCK() would lock the
> socket. However, in line 127, it unlocks socket. I am wondering that
> SOCK_UNLOCK() should be called until all the socket's parameters are done.
> In my opinion, it should be located right before ACCEPT_UNLOCK().
Some fields of the socket are protected by accept_mtx rather than the socket
lock. You can check the field locking key in socketvar.h for details:
/*-
* Locking key to struct socket:
* (a) constant after allocation, no locking required.
* (b) locked by SOCK_LOCK(so).
* (c) locked by SOCKBUF_LOCK(&so->so_rcv).
* (d) locked by SOCKBUF_LOCK(&so->so_snd).
* (e) locked by ACCEPT_LOCK().
* (f) not locked since integer reads/writes are atomic.
* (g) used only as a sleep/wakeup address, no value.
* (h) locked by global mutex so_global_mtx.
*/
...
int so_qstate; /* (e) internal state flags SQ_* */
TAILQ_HEAD(, socket) so_incomp; /* (e) queue of partial unaccepted
connections */
TAILQ_HEAD(, socket) so_comp; /* (e) queue of complete unaccepted
connections */
TAILQ_ENTRY(socket) so_list; /* (e) list of unaccepted connections
*/
u_short so_qlen; /* (e) number of unaccepted
connections
*/
u_short so_incqlen; /* (e) number of unaccepted incomplete
connections */
u_short so_qlimit; /* (e) max number queued connections
*/
The socket lock is dropped at the earliest point in each case after which no
further manipulation of the socket lock protected fields take place. The only
really dubious thing about what's there right now is the handling of socket
upcalls, which has poorly defined locking properties, but I think in the
non-accept filter case, the locking looks generally correct. Right now we
call so_upcall in different places with different locks, and some upcalls
perform activities that may require acquiring further locks, possibly in bad
orders. We rely to some extent on the behavior of the protocol to keep
certain races from happening, and that reliance is not well documented. I
have several works in progress related to socket locking which improve this to
some extent. One breaks out the single upcall function pointer into a series
of upcalls each with well defined behavior; another coalesces the various
socket locks, also resulting in well defined behavior.
Robert N M Watson
Computer Laboratory
Universty of Cambridge
More information about the freebsd-net
mailing list