diff options
author | gnn <gnn@FreeBSD.org> | 2014-01-28 20:28:32 +0000 |
---|---|---|
committer | gnn <gnn@FreeBSD.org> | 2014-01-28 20:28:32 +0000 |
commit | 5c066f64123bc86c10537ae180565c8766e3cc2c (patch) | |
tree | 4d0b96b75a192fb2c57a32f334187e4e6c60d0b7 | |
parent | 17e24564634134c9b7145fcf8d1c7d51b93c3182 (diff) | |
download | FreeBSD-src-5c066f64123bc86c10537ae180565c8766e3cc2c.zip FreeBSD-src-5c066f64123bc86c10537ae180565c8766e3cc2c.tar.gz |
Decrease lock contention within the TCP accept case by removing
the INP_INFO lock from tcp_usr_accept. As the PR/patch states
this was following the advice already in the code.
See the PR below for a full disucssion of this change and its
measured effects.
PR: 183659
Submitted by: Julian Charbon
Reviewed by: jhb
-rw-r--r-- | sys/netinet/tcp_syncache.c | 4 | ||||
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 9 |
2 files changed, 3 insertions, 10 deletions
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index af30ad1..e060beb 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -682,7 +682,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) * connection when the SYN arrived. If we can't create * the connection, abort it. */ - so = sonewconn(lso, SS_ISCONNECTED); + so = sonewconn(lso, 0); if (so == NULL) { /* * Drop the connection; we will either send a RST or @@ -922,6 +922,8 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) INP_WUNLOCK(inp); + soisconnected(so); + TCPSTAT_INC(tcps_accepts); return (so); diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 0188beb..a8dcb32 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -610,13 +610,6 @@ out: /* * Accept a connection. Essentially all the work is done at higher levels; * just return the address of the peer, storing through addr. - * - * The rationale for acquiring the tcbinfo lock here is somewhat complicated, - * and is described in detail in the commit log entry for r175612. Acquiring - * it delays an accept(2) racing with sonewconn(), which inserts the socket - * before the inpcb address/port fields are initialized. A better fix would - * prevent the socket from being placed in the listen queue until all fields - * are fully initialized. */ static int tcp_usr_accept(struct socket *so, struct sockaddr **nam) @@ -633,7 +626,6 @@ tcp_usr_accept(struct socket *so, struct sockaddr **nam) inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL")); - INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNABORTED; @@ -653,7 +645,6 @@ tcp_usr_accept(struct socket *so, struct sockaddr **nam) out: TCPDEBUG2(PRU_ACCEPT); INP_WUNLOCK(inp); - INP_INFO_RUNLOCK(&V_tcbinfo); if (error == 0) *nam = in_sockaddr(port, &addr); return error; |