diff options
author | rwatson <rwatson@FreeBSD.org> | 2006-06-04 09:31:34 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2006-06-04 09:31:34 +0000 |
commit | f0edd09c237cf984e92027b785e550153cb0ebbe (patch) | |
tree | a880d04d9d9d61e50ab898fd2b20618a8c3d5838 | |
parent | 058d883877b9a4a294fadd2a6d4f66eeb3932378 (diff) | |
download | FreeBSD-src-f0edd09c237cf984e92027b785e550153cb0ebbe.zip FreeBSD-src-f0edd09c237cf984e92027b785e550153cb0ebbe.tar.gz |
Push acquisition of pcbinfo lock out of tcp_usr_attach() into
tcp_attach() after the call to soreserve(), as it doesn't require
the global lock. Rearrange inpcb locking here also.
MFC after: 1 month
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 308740c..bf5efa6 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -120,7 +120,6 @@ tcp_usr_attach(struct socket *so, int proto, struct thread *td) inp = sotoinpcb(so); KASSERT(inp == NULL, ("tcp_usr_attach: inp != NULL")); - INP_INFO_WLOCK(&tcbinfo); TCPDEBUG1(); error = tcp_attach(so); @@ -134,7 +133,6 @@ tcp_usr_attach(struct socket *so, int proto, struct thread *td) tp = intotcpcb(inp); out: TCPDEBUG2(PRU_ATTACH); - INP_INFO_WUNLOCK(&tcbinfo); return error; } @@ -1399,17 +1397,19 @@ tcp_attach(so) int isipv6 = INP_CHECK_SOCKAF(so, AF_INET6) != 0; #endif - INP_INFO_WLOCK_ASSERT(&tcbinfo); - if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { error = soreserve(so, tcp_sendspace, tcp_recvspace); if (error) return (error); } + INP_INFO_WLOCK(&tcbinfo); error = in_pcballoc(so, &tcbinfo, "tcpinp"); - if (error) + if (error) { + INP_INFO_WUNLOCK(&tcbinfo); return (error); + } inp = sotoinpcb(so); + INP_LOCK(inp); #ifdef INET6 if (isipv6) { inp->inp_vflag |= INP_IPV6; @@ -1420,7 +1420,6 @@ tcp_attach(so) inp->inp_vflag |= INP_IPV4; tp = tcp_newtcpcb(inp); if (tp == NULL) { - INP_LOCK(inp); #ifdef INET6 if (isipv6) { in6_pcbdetach(inp); @@ -1432,9 +1431,12 @@ tcp_attach(so) #ifdef INET6 } #endif + INP_INFO_WUNLOCK(&tcbinfo); return (ENOBUFS); } tp->t_state = TCPS_CLOSED; + INP_UNLOCK(inp); + INP_INFO_WUNLOCK(&tcbinfo); return (0); } |