git: 6c452841ef9b - main - tcp: use callout(9) directly instead of pr_slowtimo

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Wed, 17 Aug 2022 18:52:16 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=6c452841ef9b3fff4602694940c25b5c6bd077e1

commit 6c452841ef9b3fff4602694940c25b5c6bd077e1
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-08-17 18:50:31 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-08-17 18:50:31 +0000

    tcp: use callout(9) directly instead of pr_slowtimo
    
    Modern TCP stacks uses multiple callouts per tcpcb, and a global
    callout is ancient artifact.  However it is still used to garbage
    collect compressed timewait entries.
    
    Reviewed by:            melifaro, tuexen
    Differential revision:  https://reviews.freebsd.org/D36159
---
 sys/netinet/in_proto.c   |  1 -
 sys/netinet/tcp_timer.c  | 26 +++++++++++++++++++++-----
 sys/netinet/tcp_var.h    |  1 -
 sys/netinet6/in6_proto.c |  1 -
 4 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index 615b4f1a4080..b9e9dbdc8f88 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -131,7 +131,6 @@ struct protosw inetsw[] = {
 	.pr_flags =		PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD|
 				    PR_CAPATTACH,
 	.pr_ctloutput =		tcp_ctloutput,
-	.pr_slowtimo =		tcp_slowtimo,
 	.pr_drain =		tcp_drain,
 	.pr_usrreqs =		&tcp_usrreqs
 },
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 8594ad3a65fa..e5af5cf5afef 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -233,15 +233,17 @@ inp_to_cpuid(struct inpcb *inp)
 }
 
 /*
- * Tcp protocol timeout routine called every 500 ms.
- * Updates timestamps used for TCP
- * causes finite state machine actions if timers expire.
+ * Legacy TCP global callout routine called every 500 ms.
+ * Used to cleanup timewait states, which lack their own callouts.
  */
-void
-tcp_slowtimo(void)
+static struct callout tcpslow_callout;
+static void
+tcp_slowtimo(void *arg __unused)
 {
+	struct epoch_tracker et;
 	VNET_ITERATOR_DECL(vnet_iter);
 
+	NET_EPOCH_ENTER(et);
 	VNET_LIST_RLOCK_NOSLEEP();
 	VNET_FOREACH(vnet_iter) {
 		CURVNET_SET(vnet_iter);
@@ -249,7 +251,21 @@ tcp_slowtimo(void)
 		CURVNET_RESTORE();
 	}
 	VNET_LIST_RUNLOCK_NOSLEEP();
+	NET_EPOCH_EXIT(et);
+
+	callout_reset_sbt(&tcpslow_callout, SBT_1MS * 500, SBT_1MS * 10,
+	    tcp_slowtimo, NULL, 0);
+}
+
+static void
+tcp_slowtimo_init(void *arg __unused)
+{
+
+        callout_init(&tcpslow_callout, 1);
+	callout_reset_sbt(&tcpslow_callout, SBT_1MS * 500, SBT_1MS * 10,
+	    tcp_slowtimo, NULL, 0);
 }
+SYSINIT(tcp_timer, SI_SUB_VNET_DONE, SI_ORDER_ANY, tcp_slowtimo_init, NULL);
 
 int	tcp_backoff[TCP_MAXRXTSHIFT + 1] =
     { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 512, 512, 512 };
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 6d6c711f25b7..fa86ab51d68b 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1187,7 +1187,6 @@ void	 tcp_tw_zone_change(void);
 int	 tcp_twcheck(struct inpcb *, struct tcpopt *, struct tcphdr *,
 	    struct mbuf *, int);
 void	 tcp_setpersist(struct tcpcb *);
-void	 tcp_slowtimo(void);
 void	 tcp_record_dsack(struct tcpcb *tp, tcp_seq start, tcp_seq end, int tlp);
 struct tcptemp *
 	 tcpip_maketemplate(struct inpcb *);
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index 2b70e38fe193..0e413dc5b048 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -166,7 +166,6 @@ struct protosw inet6sw[] = {
 				    PR_LISTEN|PR_CAPATTACH,
 	.pr_ctloutput =		tcp_ctloutput,
 #ifndef INET	/* don't call initialization, timeout, and drain routines twice */
-	.pr_slowtimo =		tcp_slowtimo,
 	.pr_drain =		tcp_drain,
 #endif
 	.pr_usrreqs =		&tcp6_usrreqs,