git: b730de8badbc - main - mld6: use callout(9) directly instead of pr_slowtimo, pr_fasttimo

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

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

commit b730de8badbc24cc2be2a5316c1a63129f387c21
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

    mld6: use callout(9) directly instead of pr_slowtimo, pr_fasttimo
    
    While here remove recursive network epoch entry in mld_fasttimo_vnet(),
    as this function is already in epoch.
    
    Reviewed by:            melifaro
    Differential revision:  https://reviews.freebsd.org/D36161
---
 sys/netinet/icmp6.h      |  2 --
 sys/netinet6/icmp6.c     | 14 --------------
 sys/netinet6/in6.c       |  3 +--
 sys/netinet6/in6_proto.c |  2 --
 sys/netinet6/mld6.c      | 42 +++++++++++++++++++++++++++---------------
 sys/netinet6/mld6_var.h  |  7 ++++---
 6 files changed, 32 insertions(+), 38 deletions(-)

diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h
index d4a103d04f00..9628c0957c4a 100644
--- a/sys/netinet/icmp6.h
+++ b/sys/netinet/icmp6.h
@@ -704,8 +704,6 @@ void	icmp6_paramerror(struct mbuf *, int);
 void	icmp6_error(struct mbuf *, int, int, int);
 void	icmp6_error2(struct mbuf *, int, int, int, struct ifnet *);
 int	icmp6_input(struct mbuf **, int *, int);
-void	icmp6_fasttimo(void);
-void	icmp6_slowtimo(void);
 void	icmp6_prepare(struct mbuf *);
 void	icmp6_redirect_input(struct mbuf *, int);
 void	icmp6_redirect_output(struct mbuf *, struct nhop_object *);
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 691943fe5d56..6b81c7a6b000 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -2127,20 +2127,6 @@ icmp6_reflect(struct mbuf *m, size_t off)
 	return;
 }
 
-void
-icmp6_fasttimo(void)
-{
-
-	mld_fasttimo();
-}
-
-void
-icmp6_slowtimo(void)
-{
-
-	mld_slowtimo();
-}
-
 static const char *
 icmp6_redirect_diag(struct in6_addr *src6, struct in6_addr *dst6,
     struct in6_addr *tgt6)
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 3386e0463637..ccdf71cfc01c 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -79,7 +79,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/priv.h>
 #include <sys/proc.h>
-#include <sys/protosw.h>
 #include <sys/time.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
@@ -733,7 +732,7 @@ in6_joingroup_legacy(struct ifnet *ifp, const struct in6_addr *mcaddr,
 		return (NULL);
 	}
 
-	delay = (delay * PR_FASTHZ) / hz;
+	delay = (delay * MLD_FASTHZ) / hz;
 
 	error = in6_joingroup(ifp, mcaddr, NULL, &imm->i6mm_maddr, delay);
 	if (error) {
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index 0e413dc5b048..f437234b71a3 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -214,8 +214,6 @@ struct protosw inet6sw[] = {
 	.pr_protocol =		IPPROTO_ICMPV6,
 	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_ctloutput =		rip6_ctloutput,
-	.pr_fasttimo =		icmp6_fasttimo,
-	.pr_slowtimo =		icmp6_slowtimo,
 	.pr_usrreqs =		&rip6_usrreqs
 },
 {
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index 548ea55ef715..60dc3a59eb4f 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -75,7 +75,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
-#include <sys/protosw.h>
 #include <sys/sysctl.h>
 #include <sys/kernel.h>
 #include <sys/callout.h>
@@ -670,7 +669,7 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
 	KASSERT(mli != NULL, ("%s: no mld_ifsoftc for ifp %p", __func__, ifp));
 	mld_set_version(mli, MLD_VERSION_1);
 
-	timer = (ntohs(mld->mld_maxdelay) * PR_FASTHZ) / MLD_TIMER_SCALE;
+	timer = (ntohs(mld->mld_maxdelay) * MLD_FASTHZ) / MLD_TIMER_SCALE;
 	if (timer == 0)
 		timer = 1;
 
@@ -821,7 +820,7 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
 		maxdelay = (MLD_MRC_MANT(maxdelay) | 0x1000) <<
 			   (MLD_MRC_EXP(maxdelay) + 3);
 	}
-	timer = (maxdelay * PR_FASTHZ) / MLD_TIMER_SCALE;
+	timer = (maxdelay * MLD_FASTHZ) / MLD_TIMER_SCALE;
 	if (timer == 0)
 		timer = 1;
 
@@ -1294,14 +1293,17 @@ mld_input(struct mbuf **mp, int off, int icmp6len)
  * Fast timeout handler (global).
  * VIMAGE: Timeout handlers are expected to service all vimages.
  */
-void
-mld_fasttimo(void)
+static struct callout mldfast_callout;
+static void
+mld_fasttimo(void *arg __unused)
 {
+	struct epoch_tracker et;
 	struct in6_multi_head inmh;
 	VNET_ITERATOR_DECL(vnet_iter);
 
 	SLIST_INIT(&inmh);
 
+	NET_EPOCH_ENTER(et);
 	VNET_LIST_RLOCK_NOSLEEP();
 	VNET_FOREACH(vnet_iter) {
 		CURVNET_SET(vnet_iter);
@@ -1309,7 +1311,10 @@ mld_fasttimo(void)
 		CURVNET_RESTORE();
 	}
 	VNET_LIST_RUNLOCK_NOSLEEP();
+	NET_EPOCH_EXIT(et);
 	in6m_release_list_deferred(&inmh);
+
+	callout_reset(&mldfast_callout, hz / MLD_FASTHZ, mld_fasttimo, NULL);
 }
 
 /*
@@ -1320,7 +1325,6 @@ mld_fasttimo(void)
 static void
 mld_fasttimo_vnet(struct in6_multi_head *inmh)
 {
-	struct epoch_tracker     et;
 	struct mbufq		 scq;	/* State-change packets */
 	struct mbufq		 qrq;	/* Query response packets */
 	struct ifnet		*ifp;
@@ -1380,12 +1384,11 @@ mld_fasttimo_vnet(struct in6_multi_head *inmh)
 
 		if (mli->mli_version == MLD_VERSION_2) {
 			uri_fasthz = MLD_RANDOM_DELAY(mli->mli_uri *
-			    PR_FASTHZ);
+			    MLD_FASTHZ);
 			mbufq_init(&qrq, MLD_MAX_G_GS_PACKETS);
 			mbufq_init(&scq, MLD_MAX_STATE_CHANGE_PACKETS);
 		}
 
-		NET_EPOCH_ENTER(et);
 		IF_ADDR_WLOCK(ifp);
 		CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
 			inm = in6m_ifmultiaddr_get_inm(ifma);
@@ -1424,7 +1427,6 @@ mld_fasttimo_vnet(struct in6_multi_head *inmh)
 			mld_dispatch_queue(&scq, 0);
 			break;
 		}
-		NET_EPOCH_EXIT(et);
 	}
 
 out_locked:
@@ -1616,7 +1618,7 @@ mld_set_version(struct mld_ifsoftc *mli, const int version)
 		 * Section 9.12.
 		 */
 		old_version_timer = (mli->mli_rv * mli->mli_qi) + mli->mli_qri;
-		old_version_timer *= PR_SLOWHZ;
+		old_version_timer *= MLD_SLOWHZ;
 		mli->mli_v1_timer = old_version_timer;
 	}
 
@@ -1707,8 +1709,9 @@ mld_v2_cancel_link_timers(struct mld_ifsoftc *mli)
  * Global slowtimo handler.
  * VIMAGE: Timeout handlers are expected to service all vimages.
  */
-void
-mld_slowtimo(void)
+static struct callout mldslow_callout;
+static void
+mld_slowtimo(void *arg __unused)
 {
 	VNET_ITERATOR_DECL(vnet_iter);
 
@@ -1719,6 +1722,8 @@ mld_slowtimo(void)
 		CURVNET_RESTORE();
 	}
 	VNET_LIST_RUNLOCK_NOSLEEP();
+
+	callout_reset(&mldslow_callout, hz / MLD_SLOWHZ, mld_slowtimo, NULL);
 }
 
 /*
@@ -1853,7 +1858,7 @@ mld_v1_transmit_report(struct in6_multi *in6m, const int type)
  *
  * If delay is non-zero, and the state change is an initial multicast
  * join, the state change report will be delayed by 'delay' ticks
- * in units of PR_FASTHZ if MLDv1 is active on the link; otherwise
+ * in units of MLD_FASTHZ if MLDv1 is active on the link; otherwise
  * the initial MLDv2 state change report will be delayed by whichever
  * is sooner, a pending state-change timer or delay itself.
  *
@@ -1935,7 +1940,7 @@ out_locked:
  *  initial state of the membership.
  *
  * If the delay argument is non-zero, then we must delay sending the
- * initial state change for delay ticks (in units of PR_FASTHZ).
+ * initial state change for delay ticks (in units of MLD_FASTHZ).
  */
 static int
 mld_initial_join(struct in6_multi *inm, struct mld_ifsoftc *mli,
@@ -2003,7 +2008,7 @@ mld_initial_join(struct in6_multi *inm, struct mld_ifsoftc *mli,
 			 * and delay sending the initial MLDv1 report
 			 * by not transitioning to the IDLE state.
 			 */
-			odelay = MLD_RANDOM_DELAY(MLD_V1_MAX_RI * PR_FASTHZ);
+			odelay = MLD_RANDOM_DELAY(MLD_V1_MAX_RI * MLD_FASTHZ);
 			if (delay) {
 				inm->in6m_timer = max(delay, odelay);
 				V_current_state_timers_running6 = 1;
@@ -3268,6 +3273,11 @@ mld_init(void *unused __unused)
 	mld_po.ip6po_hbh = &mld_ra.hbh;
 	mld_po.ip6po_prefer_tempaddr = IP6PO_TEMPADDR_NOTPREFER;
 	mld_po.ip6po_flags = IP6PO_DONTFRAG;
+
+	callout_init(&mldslow_callout, 1);
+	callout_reset(&mldslow_callout, hz / MLD_SLOWHZ, mld_slowtimo, NULL);
+	callout_init(&mldfast_callout, 1);
+	callout_reset(&mldfast_callout, hz / MLD_FASTHZ, mld_fasttimo, NULL);
 }
 SYSINIT(mld_init, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE, mld_init, NULL);
 
@@ -3276,6 +3286,8 @@ mld_uninit(void *unused __unused)
 {
 
 	CTR1(KTR_MLD, "%s: tearing down", __func__);
+	callout_drain(&mldslow_callout);
+	callout_drain(&mldfast_callout);
 	MLD_LOCK_DESTROY();
 }
 SYSUNINIT(mld_uninit, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE, mld_uninit, NULL);
diff --git a/sys/netinet6/mld6_var.h b/sys/netinet6/mld6_var.h
index 0aedde275f1b..29e859d653ec 100644
--- a/sys/netinet6/mld6_var.h
+++ b/sys/netinet6/mld6_var.h
@@ -83,7 +83,7 @@
 #define MLD_MAX_STATE_CHANGE_PACKETS	8 /* # of packets per state change */
 #define MLD_MAX_RESPONSE_PACKETS	16 /* # of packets for general query */
 #define MLD_MAX_RESPONSE_BURST		4 /* # of responses to send at once */
-#define MLD_RESPONSE_BURST_INTERVAL	(PR_FASTHZ / 2)	/* 500ms */
+#define MLD_RESPONSE_BURST_INTERVAL	(MLD_FASTHZ / 2)	/* 500ms */
 
 /*
  * MLD-specific mbuf flags.
@@ -165,10 +165,11 @@ int	mld_change_state(struct in6_multi *, const int);
 struct mld_ifsoftc *
 	mld_domifattach(struct ifnet *);
 void	mld_domifdetach(struct ifnet *);
-void	mld_fasttimo(void);
 void	mld_ifdetach(struct ifnet *, struct in6_multi_head *);
 int	mld_input(struct mbuf **, int, int);
-void	mld_slowtimo(void);
+
+#define	MLD_SLOWHZ	2	/* 2 slow timeouts per second */
+#define	MLD_FASTHZ	5	/* 5 fast timeouts per second */
 
 #ifdef SYSCTL_DECL
 SYSCTL_DECL(_net_inet6_mld);