summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-05-01 11:11:38 +0000
committerrwatson <rwatson@FreeBSD.org>2005-05-01 11:11:38 +0000
commit6db3b00e40a9522fdeeff49475bab0a71628892f (patch)
tree81c23c20334d1b6ee26d6e705c776346123c2a5c /sys
parentfa923d7b239df09fb9b54b7163b7d00db8ec0788 (diff)
downloadFreeBSD-src-6db3b00e40a9522fdeeff49475bab0a71628892f.zip
FreeBSD-src-6db3b00e40a9522fdeeff49475bab0a71628892f.tar.gz
Slide unlocking of the tcbinfo lock earlier in tcp_usr_send(), as it's
needed only for implicit connect cases. Under load, especially on SMP, this can greatly reduce contention on the tcbinfo lock. NB: Ambiguities about the state of so_pcb need to be resolved so that all use of the tcbinfo lock in non-implicit connection cases can be eliminated. Submited by: Kazuaki Oda <kaakun at highway dot ne dot jp>
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp_usrreq.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 6ff4873..310d52d 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -620,6 +620,7 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
struct inpcb *inp;
struct tcpcb *tp;
const int inirw = INI_WRITE;
+ int unlocked = 0;
#ifdef INET6
int isipv6;
#endif
@@ -694,6 +695,8 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
socantsendmore(so);
tp = tcp_usrclosed(tp);
}
+ INP_INFO_WUNLOCK(&tcbinfo);
+ unlocked = 1;
if (tp != NULL) {
if (flags & PRUS_MORETOCOME)
tp->t_flags |= TF_MORETOCOME;
@@ -737,13 +740,21 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
tp->snd_wnd = TTCP_CLIENT_SND_WND;
tcp_mss(tp, -1);
}
+ INP_INFO_WUNLOCK(&tcbinfo);
+ unlocked = 1;
tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
tp->t_force = 1;
error = tcp_output(tp);
tp->t_force = 0;
}
- COMMON_END((flags & PRUS_OOB) ? PRU_SENDOOB :
- ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
+out:
+ TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB :
+ ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
+ if (tp)
+ INP_UNLOCK(inp);
+ if (!unlocked)
+ INP_INFO_WUNLOCK(&tcbinfo);
+ return (error):
}
/*
OpenPOWER on IntegriCloud