summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_timer.c
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2007-06-09 17:49:39 +0000
committerandre <andre@FreeBSD.org>2007-06-09 17:49:39 +0000
commit01595fc7b29146940f470ccd08f8a1cc63cda924 (patch)
treec98dffc6b58d75e6b53d015fe6b487cf3c34cc26 /sys/netinet/tcp_timer.c
parent6787a70c5fee91a175d747b25a883bd830ff1418 (diff)
downloadFreeBSD-src-01595fc7b29146940f470ccd08f8a1cc63cda924.zip
FreeBSD-src-01595fc7b29146940f470ccd08f8a1cc63cda924.tar.gz
Handle a race condition on >2 core machines in tcp_timer() when
a timer issues a shutdown and a simultaneous close on the socket happens. This race condition is inherent in the current socket/ inpcb life cycle system but can be handled well. Reported by: kris Tested by: kris (on 8-core machine)
Diffstat (limited to 'sys/netinet/tcp_timer.c')
-rw-r--r--sys/netinet/tcp_timer.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index c861f12..5afcbef 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -386,8 +386,14 @@ shutdown:
INP_INFO_WLOCK(&tcbinfo);
INP_LOCK(inp);
- /* When tp is gone we've lost the race. */
- if (inp->inp_ppcb == NULL) {
+ /*
+ * XXX: When our tcpcb went into TIMEWAIT, is gone or no
+ * longer the one we used to work with we've lost the race.
+ * This race is inherent in the current socket/inpcb life
+ * cycle system.
+ */
+ if ((inp->inp_vflag & INP_TIMEWAIT) || inp->inp_ppcb == NULL ||
+ inp->inp_ppcb != tp) {
CTR3(KTR_NET, "%p %s inp %p lost shutdown race",
tp, __func__, inp);
tcp_timer_race++;
OpenPOWER on IntegriCloud