summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_timer.c
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2018-01-23 21:41:17 +0000
committerbluhm <bluhm@openbsd.org>2018-01-23 21:41:17 +0000
commit9acddc59a51489e71fb2f560a3a0f0570a1ac983 (patch)
tree950781eb9bbc67ef6ea0333a80fb1829db2308b3 /sys/netinet/tcp_timer.c
parentAlthough it is a dead store here, always reassign the tcpcb after (diff)
downloadwireguard-openbsd-9acddc59a51489e71fb2f560a3a0f0570a1ac983.tar.xz
wireguard-openbsd-9acddc59a51489e71fb2f560a3a0f0570a1ac983.zip
The TCP reaper timeout was still imlemented as soft timeout. So
it could run immediately and was not synchronized with the TCP timeouts, although that was the intension when it was introduced in revision 1.85. Convert the reaper to an ordinary TCP timeout so it is scheduled on the same timeout thread after all timeouts have finished. A net lock is not necessary as the process calling tcp_close() will not access the tcpcb after arming the reaper timeout. OK mikeb@
Diffstat (limited to 'sys/netinet/tcp_timer.c')
-rw-r--r--sys/netinet/tcp_timer.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index acacbe7dcf8..37641bde19e 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_timer.c,v 1.61 2018/01/23 21:06:47 bluhm Exp $ */
+/* $OpenBSD: tcp_timer.c,v 1.62 2018/01/23 21:41:17 bluhm Exp $ */
/* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */
/*
@@ -70,12 +70,14 @@ void tcp_timer_rexmt(void *);
void tcp_timer_persist(void *);
void tcp_timer_keep(void *);
void tcp_timer_2msl(void *);
+void tcp_timer_reaper(void *);
const tcp_timer_func_t tcp_timer_funcs[TCPT_NTIMERS] = {
tcp_timer_rexmt,
tcp_timer_persist,
tcp_timer_keep,
tcp_timer_2msl,
+ tcp_timer_reaper,
};
/*
@@ -464,3 +466,20 @@ tcp_timer_2msl(void *arg)
out:
NET_UNLOCK();
}
+
+void
+tcp_timer_reaper(void *arg)
+{
+ struct tcpcb *tp = arg;
+
+ /*
+ * This timer is necessary to delay the pool_put() after all timers
+ * have finished, even if they were sleeping to grab the net lock.
+ * Putting the pool_put() in a timer is sufficinet as all timers run
+ * from the same timeout thread. Note that neither softnet thread nor
+ * user process may access the tcpcb after arming the reaper timer.
+ * Freeing may run in parallel as it does not grab the net lock.
+ */
+ pool_put(&tcpcb_pool, tp);
+ tcpstat_inc(tcps_closed);
+}