socket lock
Son, Sonny
Sonny.Son at netapp.com
Wed Feb 26 22:47:35 UTC 2014
Hi all,
Can somebody explain me how socket data structure-i.e. 'struct socket'-is protected in FreeBSD? It seems that socket is accessed and modified without lock in some places. As an instance, the following code reads and/or modifies various socket fields including so_error without socket lock held:
int
sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio,
struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
{
long space, resid;
int clen = 0, error, dontroute;
#ifdef ZERO_COPY_SOCKETS
int atomic = sosendallatonce(so) || top;
#endif
KASSERT(so->so_type == SOCK_DGRAM, ("sodgram_send: !SOCK_DGRAM"));
KASSERT(so->so_proto->pr_flags & PR_ATOMIC,
("sodgram_send: !PR_ATOMIC"));
if (uio != NULL)
resid = uio->uio_resid;
else
resid = top->m_pkthdr.len;
/*
* In theory resid should be unsigned. However, space must be
* signed, as it might be less than 0 if we over-committed, and we
* must use a signed comparison of space and resid. On the other
* hand, a negative resid causes us to loop sending 0-length
* segments to the protocol.
*/
if (resid < 0) {
error = EINVAL;
goto out;
}
dontroute =
(flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0;
if (td != NULL)
td->td_ru.ru_msgsnd++;
if (control != NULL)
clen = control->m_len;
SOCKBUF_LOCK(&so->so_snd);
if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
SOCKBUF_UNLOCK(&so->so_snd);
error = EPIPE;
goto out;
}
if (so->so_error) {
error = so->so_error;
so->so_error = 0; <=========== we do have socket's send buffer lock but not socket lock (, which is socket recv buffer lock)
SOCKBUF_UNLOCK(&so->so_snd);
goto out;
}
I am sorry if this was already discussed before...
Thank you!
More information about the freebsd-net
mailing list