git: 160f01f09f4b - main - ip_reass: use callout(9) directly instead of pr_slowtimo

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

URL: https://cgit.FreeBSD.org/src/commit/?id=160f01f09f4b5a50cd752fe1d55a83f5f2c9f9fc

commit 160f01f09f4b5a50cd752fe1d55a83f5f2c9f9fc
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

    ip_reass: use callout(9) directly instead of pr_slowtimo
    
    Reviewed by:            melifaro
    Differential revision:  https://reviews.freebsd.org/D36236
---
 sys/netinet/in_proto.c |  1 -
 sys/netinet/ip_input.c | 20 ----------------
 sys/netinet/ip_reass.c | 65 ++++++++++++++++++++++++++++++++------------------
 sys/netinet/ip_var.h   |  1 -
 4 files changed, 42 insertions(+), 45 deletions(-)

diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index b589441b20d3..615b4f1a4080 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -113,7 +113,6 @@ struct protosw inetsw[] = {
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_IP,
 	.pr_flags =		PR_CAPATTACH,
-	.pr_slowtimo =		ip_slowtimo,
 	.pr_drain =		ip_drain,
 	.pr_usrreqs =		&nousrreqs
 },
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 7fdabf24b2a7..ca451ef48649 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -102,7 +102,6 @@ CTASSERT(sizeof(struct ip) == 20);
 /* IP reassembly functions are defined in ip_reass.c. */
 extern void ipreass_init(void);
 extern void ipreass_drain(void);
-extern void ipreass_slowtimo(void);
 #ifdef VIMAGE
 extern void ipreass_destroy(void);
 #endif
@@ -846,25 +845,6 @@ bad:
 	m_freem(m);
 }
 
-/*
- * IP timer processing;
- * if a timer expires on a reassembly
- * queue, discard it.
- */
-void
-ip_slowtimo(void)
-{
-	VNET_ITERATOR_DECL(vnet_iter);
-
-	VNET_LIST_RLOCK_NOSLEEP();
-	VNET_FOREACH(vnet_iter) {
-		CURVNET_SET(vnet_iter);
-		ipreass_slowtimo();
-		CURVNET_RESTORE();
-	}
-	VNET_LIST_RUNLOCK_NOSLEEP();
-}
-
 void
 ip_drain(void)
 {
diff --git a/sys/netinet/ip_reass.c b/sys/netinet/ip_reass.c
index db32e6a312f2..b436d6282206 100644
--- a/sys/netinet/ip_reass.c
+++ b/sys/netinet/ip_reass.c
@@ -93,7 +93,6 @@ VNET_DEFINE_STATIC(int, ipreass_maxbucketsize);
 
 void		ipreass_init(void);
 void		ipreass_drain(void);
-void		ipreass_slowtimo(void);
 #ifdef VIMAGE
 void		ipreass_destroy(void);
 #endif
@@ -556,6 +555,48 @@ done:
 #undef GETIP
 }
 
+/*
+ * If a timer expires on a reassembly queue, discard it.
+ */
+static struct callout ipreass_callout;
+static void
+ipreass_slowtimo(void *arg __unused)
+{
+	VNET_ITERATOR_DECL(vnet_iter);
+	struct ipq *fp, *tmp;
+
+	if (atomic_load_int(&nfrags) == 0)
+		return;
+
+	VNET_FOREACH(vnet_iter) {
+		CURVNET_SET(vnet_iter);
+		for (int i = 0; i < IPREASS_NHASH; i++) {
+			if (TAILQ_EMPTY(&V_ipq[i].head))
+				continue;
+			IPQ_LOCK(i);
+			TAILQ_FOREACH_SAFE(fp, &V_ipq[i].head, ipq_list, tmp)
+			if (--fp->ipq_ttl == 0)
+				ipq_timeout(&V_ipq[i], fp);
+			IPQ_UNLOCK(i);
+		}
+		CURVNET_RESTORE();
+	}
+	VNET_LIST_RUNLOCK_NOSLEEP();
+
+	callout_reset_sbt(&ipreass_callout, SBT_1MS * 500, SBT_1MS * 10,
+	    ipreass_slowtimo, NULL, 0);
+}
+
+static void
+ipreass_timer_init(void *arg __unused)
+{
+
+	callout_init(&ipreass_callout, 1);
+	callout_reset_sbt(&ipreass_callout, SBT_1MS * 500, SBT_1MS * 10,
+	    ipreass_slowtimo, NULL, 0);
+}
+SYSINIT(ipreass, SI_SUB_VNET_DONE, SI_ORDER_ANY, ipreass_timer_init, NULL);
+
 /*
  * Initialize IP reassembly structures.
  */
@@ -585,28 +626,6 @@ ipreass_init(void)
 	}
 }
 
-/*
- * If a timer expires on a reassembly queue, discard it.
- */
-void
-ipreass_slowtimo(void)
-{
-	struct ipq *fp, *tmp;
-
-	if (atomic_load_int(&nfrags) == 0)
-		return;
-
-	for (int i = 0; i < IPREASS_NHASH; i++) {
-		if (TAILQ_EMPTY(&V_ipq[i].head))
-			continue;
-		IPQ_LOCK(i);
-		TAILQ_FOREACH_SAFE(fp, &V_ipq[i].head, ipq_list, tmp)
-		if (--fp->ipq_ttl == 0)
-			ipq_timeout(&V_ipq[i], fp);
-		IPQ_UNLOCK(i);
-	}
-}
-
 /*
  * Drain off all datagram fragments.
  */
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index ce0efcfead1b..8711e0291379 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -228,7 +228,6 @@ struct mbuf *
 	ip_reass(struct mbuf *);
 void	ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
 	    struct mbuf *);
-void	ip_slowtimo(void);
 void	ip_fillid(struct ip *);
 int	rip_ctloutput(struct socket *, struct sockopt *);
 void	rip_ctlinput(int, struct sockaddr *, void *);