git: 187ea09fbbdd - stable/13 - uipc: create dedicated lists for fast and slow timeout callbacks

Mateusz Guzik mjg at FreeBSD.org
Mon Aug 23 12:34:32 UTC 2021


The branch stable/13 has been updated by mjg:

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

commit 187ea09fbbddff0d79d4a154e235a11e251dbad4
Author:     Mateusz Guzik <mjg at FreeBSD.org>
AuthorDate: 2021-08-15 21:41:47 +0000
Commit:     Mateusz Guzik <mjg at FreeBSD.org>
CommitDate: 2021-08-23 12:32:01 +0000

    uipc: create dedicated lists for fast and slow timeout callbacks
    
    This avoids having to walk all possible protocols only to check if they
    have one (vast majority does not).
    
    Original patch by kevans at .
    
    Reviewed by:    kevans
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    
    (cherry picked from commit e0a17c3f063fd51430fb2b4f5bc667f79d2967c2)
---
 sys/kern/uipc_domain.c | 55 ++++++++++++++++++++++++++++++++++++++++----------
 sys/sys/protosw.h      |  4 ++++
 2 files changed, 48 insertions(+), 11 deletions(-)

diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index 60e30eb1ae00..76c0364f6824 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/rmlock.h>
 #include <sys/socketvar.h>
 #include <sys/systm.h>
 
@@ -74,6 +75,14 @@ static struct callout pfslow_callout;
 static void	pffasttimo(void *);
 static void	pfslowtimo(void *);
 
+static struct rmlock pftimo_lock;
+RM_SYSINIT(pftimo_lock, &pftimo_lock, "pftimo");
+
+static LIST_HEAD(, protosw) pffast_list =
+    LIST_HEAD_INITIALIZER(pffast_list);
+static LIST_HEAD(, protosw) pfslow_list =
+    LIST_HEAD_INITIALIZER(pfslow_list);
+
 struct domain *domains;		/* registered protocol domains */
 int domain_init_status = 0;
 static struct mtx dom_mtx;		/* domain list lock */
@@ -175,8 +184,16 @@ domain_init(void *arg)
 
 	if (dp->dom_init)
 		(*dp->dom_init)();
-	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
+	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
 		protosw_init(pr);
+		rm_wlock(&pftimo_lock);
+		if (pr->pr_fasttimo != NULL)
+			LIST_INSERT_HEAD(&pffast_list, pr, pr_fasttimos);
+		if (pr->pr_slowtimo != NULL)
+			LIST_INSERT_HEAD(&pfslow_list, pr, pr_slowtimos);
+		rm_wunlock(&pftimo_lock);
+	}
+
 	/*
 	 * update global information about maximums
 	 */
@@ -381,6 +398,13 @@ pf_proto_register(int family, struct protosw *npr)
 	/* Copy the new struct protosw over the spacer. */
 	bcopy(npr, fpr, sizeof(*fpr));
 
+	rm_wlock(&pftimo_lock);
+	if (fpr->pr_fasttimo != NULL)
+		LIST_INSERT_HEAD(&pffast_list, fpr, pr_fasttimos);
+	if (fpr->pr_slowtimo != NULL)
+		LIST_INSERT_HEAD(&pfslow_list, fpr, pr_slowtimos);
+	rm_wunlock(&pftimo_lock);
+
 	/* Job is done, no more protection required. */
 	mtx_unlock(&dom_mtx);
 
@@ -441,6 +465,13 @@ pf_proto_unregister(int family, int protocol, int type)
 		return (EPROTONOSUPPORT);
 	}
 
+	rm_wlock(&pftimo_lock);
+	if (dpr->pr_fasttimo != NULL)
+		LIST_REMOVE(dpr, pr_fasttimos);
+	if (dpr->pr_slowtimo != NULL)
+		LIST_REMOVE(dpr, pr_slowtimos);
+	rm_wunlock(&pftimo_lock);
+
 	/* De-orbit the protocol and make the slot available again. */
 	dpr->pr_type = 0;
 	dpr->pr_domain = dp;
@@ -477,31 +508,33 @@ pfctlinput(int cmd, struct sockaddr *sa)
 static void
 pfslowtimo(void *arg)
 {
+	struct rm_priotracker tracker;
 	struct epoch_tracker et;
-	struct domain *dp;
 	struct protosw *pr;
 
+	rm_rlock(&pftimo_lock, &tracker);
 	NET_EPOCH_ENTER(et);
-	for (dp = domains; dp; dp = dp->dom_next)
-		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
-			if (pr->pr_slowtimo)
-				(*pr->pr_slowtimo)();
+	LIST_FOREACH(pr, &pfslow_list, pr_slowtimos) {
+		(*pr->pr_slowtimo)();
+	}
 	NET_EPOCH_EXIT(et);
+	rm_runlock(&pftimo_lock, &tracker);
 	callout_reset(&pfslow_callout, hz/2, pfslowtimo, NULL);
 }
 
 static void
 pffasttimo(void *arg)
 {
+	struct rm_priotracker tracker;
 	struct epoch_tracker et;
-	struct domain *dp;
 	struct protosw *pr;
 
+	rm_rlock(&pftimo_lock, &tracker);
 	NET_EPOCH_ENTER(et);
-	for (dp = domains; dp; dp = dp->dom_next)
-		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
-			if (pr->pr_fasttimo)
-				(*pr->pr_fasttimo)();
+	LIST_FOREACH(pr, &pffast_list, pr_fasttimos) {
+		(*pr->pr_fasttimo)();
+	}
 	NET_EPOCH_EXIT(et);
+	rm_runlock(&pftimo_lock, &tracker);
 	callout_reset(&pffast_callout, hz/5, pffasttimo, NULL);
 }
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index 9c3139c866bd..5c876a2052d5 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -35,6 +35,8 @@
 #ifndef _SYS_PROTOSW_H_
 #define _SYS_PROTOSW_H_
 
+#include <sys/queue.h>
+
 /* Forward declare these structures referenced from prototypes below. */
 struct kaiocb;
 struct mbuf;
@@ -93,6 +95,8 @@ struct protosw {
 	pr_drain_t *pr_drain;		/* flush any excess space possible */
 
 	struct	pr_usrreqs *pr_usrreqs;	/* user-protocol hook */
+	LIST_ENTRY(protosw)  pr_fasttimos;
+	LIST_ENTRY(protosw)  pr_slowtimos;
 };
 /*#endif*/
 


More information about the dev-commits-src-all mailing list