git: 72b14da466bb - stable/12 - pf: switch kif counters to pf_counter_u64

Mateusz Guzik mjg at FreeBSD.org
Wed Aug 11 13:25:20 UTC 2021


The branch stable/12 has been updated by mjg:

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

commit 72b14da466bbb9eebf2400930abefce8de47261d
Author:     Mateusz Guzik <mjg at FreeBSD.org>
AuthorDate: 2021-07-23 10:29:46 +0000
Commit:     Mateusz Guzik <mjg at FreeBSD.org>
CommitDate: 2021-08-11 12:21:48 +0000

    pf: switch kif counters to pf_counter_u64
    
    Reviewed by:    kp
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    
    (cherry picked from commit d40d4b3ed788b05697541b9ae94b1960ff2cf6f6)
---
 sys/net/pfvar.h           | 17 +++++++++++--
 sys/netpfil/pf/pf.c       | 51 +++++++++++++++++++++++++++++++++++---
 sys/netpfil/pf/pf_if.c    | 62 +++++++++++++++++++++++++++++++++++------------
 sys/netpfil/pf/pf_ioctl.c | 17 +++++++++++++
 4 files changed, 126 insertions(+), 21 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 7c1e92d39470..e8cf8b1e6019 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1255,14 +1255,17 @@ struct pfi_kkif {
 	} _pfik_glue;
 #define	pfik_tree	_pfik_glue._pfik_tree
 #define	pfik_list	_pfik_glue._pfik_list
-	counter_u64_t			 pfik_packets[2][2][2];
-	counter_u64_t			 pfik_bytes[2][2][2];
+	struct pf_counter_u64		 pfik_packets[2][2][2];
+	struct pf_counter_u64		 pfik_bytes[2][2][2];
 	u_int32_t			 pfik_tzero;
 	u_int				 pfik_flags;
 	struct ifnet			*pfik_ifp;
 	struct ifg_group		*pfik_group;
 	u_int				 pfik_rulerefs;
 	TAILQ_HEAD(, pfi_dynaddr)	 pfik_dynaddrs;
+#ifdef PF_WANT_32_TO_64_COUNTER
+	LIST_ENTRY(pfi_kkif)		 pfik_allkiflist;
+#endif
 };
 #endif
 
@@ -1848,6 +1851,16 @@ VNET_DECLARE(struct pf_altqqueue *,	 pf_altq_ifs_inactive);
 VNET_DECLARE(struct pf_krulequeue, pf_unlinked_rules);
 #define	V_pf_unlinked_rules	VNET(pf_unlinked_rules)
 
+#ifdef PF_WANT_32_TO_64_COUNTER
+LIST_HEAD(allkiflist_head, pfi_kkif);
+VNET_DECLARE(struct allkiflist_head, pf_allkiflist);
+#define V_pf_allkiflist     VNET(pf_allkiflist)
+VNET_DECLARE(size_t, pf_allkifcount);
+#define V_pf_allkifcount     VNET(pf_allkifcount)
+VNET_DECLARE(struct pfi_kkif *, pf_kifmarker);
+#define V_pf_kifmarker     VNET(pf_kifmarker)
+#endif
+
 void				 pf_initialize(void);
 void				 pf_mtag_initialize(void);
 void				 pf_mtag_cleanup(void);
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 1ba95754bd32..3dcea7e59bd0 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -1528,6 +1528,48 @@ pf_status_counter_u64_periodic(void)
 	}
 }
 
+static void
+pf_kif_counter_u64_periodic(void)
+{
+	struct pfi_kkif *kif;
+	size_t r, run;
+
+	PF_RULES_RASSERT();
+
+	if (__predict_false(V_pf_allkifcount == 0)) {
+		return;
+	}
+
+	if ((V_pf_counter_periodic_iter % (pf_purge_thread_period * 10 * 300)) != 0) {
+		return;
+	}
+
+	run = V_pf_allkifcount / 10;
+	if (run < 5)
+		run = 5;
+
+	for (r = 0; r < run; r++) {
+		kif = LIST_NEXT(V_pf_kifmarker, pfik_allkiflist);
+		if (kif == NULL) {
+			LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
+			LIST_INSERT_HEAD(&V_pf_allkiflist, V_pf_kifmarker, pfik_allkiflist);
+			break;
+		}
+
+		LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
+		LIST_INSERT_AFTER(kif, V_pf_kifmarker, pfik_allkiflist);
+
+		for (int i = 0; i < 2; i++) {
+			for (int j = 0; j < 2; j++) {
+				for (int k = 0; k < 2; k++) {
+					pf_counter_u64_periodic(&kif->pfik_packets[i][j][k]);
+					pf_counter_u64_periodic(&kif->pfik_bytes[i][j][k]);
+				}
+			}
+		}
+	}
+}
+
 static void
 pf_counter_u64_periodic_main(void)
 {
@@ -1538,6 +1580,7 @@ pf_counter_u64_periodic_main(void)
 	PF_RULES_RLOCK();
 	pf_counter_u64_critical_enter();
 	pf_status_counter_u64_periodic();
+	pf_kif_counter_u64_periodic();
 	pf_counter_u64_critical_exit();
 	PF_RULES_RUNLOCK();
 }
@@ -6468,9 +6511,9 @@ done:
 		    (s == NULL));
 	}
 
-	counter_u64_add(kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS],
+	pf_counter_u64_add(&kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS],
 	    pd.tot_len);
-	counter_u64_add(kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS],
+	pf_counter_u64_add(&kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS],
 	    1);
 
 	if (action == PF_PASS || r->action == PF_DROP) {
@@ -6876,9 +6919,9 @@ done:
 		    &pd, (s == NULL));
 	}
 
-	counter_u64_add(kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS],
+	pf_counter_u64_add(&kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS],
 	    pd.tot_len);
-	counter_u64_add(kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS],
+	pf_counter_u64_add(&kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS],
 	    1);
 
 	if (action == PF_PASS || r->action == PF_DROP) {
diff --git a/sys/netpfil/pf/pf_if.c b/sys/netpfil/pf/pf_if.c
index 9c10be3b3b77..ff2038138068 100644
--- a/sys/netpfil/pf/pf_if.c
+++ b/sys/netpfil/pf/pf_if.c
@@ -69,6 +69,12 @@ VNET_DEFINE_STATIC(int,	pfi_buffer_max);
 #define	V_pfi_buffer_cnt	 VNET(pfi_buffer_cnt)
 #define	V_pfi_buffer_max	 VNET(pfi_buffer_max)
 
+#ifdef PF_WANT_32_TO_64_COUNTER
+VNET_DEFINE(struct allkiflist_head, pf_allkiflist);
+VNET_DEFINE(size_t, pf_allkifcount);
+VNET_DEFINE(struct pfi_kkif *, pf_kifmarker);
+#endif
+
 eventhandler_tag	 pfi_attach_cookie;
 eventhandler_tag	 pfi_detach_cookie;
 eventhandler_tag	 pfi_attach_group_cookie;
@@ -198,6 +204,9 @@ struct pfi_kkif*
 pf_kkif_create(int flags)
 {
 	struct pfi_kkif *kif;
+#ifdef PF_WANT_32_TO_64_COUNTER
+	bool wowned;
+#endif
 
 	kif = malloc(sizeof(*kif), PFI_MTYPE, flags | M_ZERO);
 	if (! kif)
@@ -206,13 +215,12 @@ pf_kkif_create(int flags)
 	for (int i = 0; i < 2; i++) {
 		for (int j = 0; j < 2; j++) {
 			for (int k = 0; k < 2; k++) {
-				kif->pfik_packets[i][j][k] =
-				    counter_u64_alloc(flags);
-				kif->pfik_bytes[i][j][k] =
-				    counter_u64_alloc(flags);
+				if (pf_counter_u64_init(&kif->pfik_packets[i][j][k], flags) != 0) {
+					pf_kkif_free(kif);
+					return (NULL);
+				}
 
-				if (! kif->pfik_packets[i][j][k] ||
-				    ! kif->pfik_bytes[i][j][k]) {
+				if (pf_counter_u64_init(&kif->pfik_bytes[i][j][k], flags) != 0) {
 					pf_kkif_free(kif);
 					return (NULL);
 				}
@@ -220,20 +228,44 @@ pf_kkif_create(int flags)
 		}
 	}
 
+#ifdef PF_WANT_32_TO_64_COUNTER
+	wowned = PF_RULES_WOWNED();
+	if (!wowned)
+		PF_RULES_WLOCK();
+	LIST_INSERT_HEAD(&V_pf_allkiflist, kif, pfik_allkiflist);
+	V_pf_allkifcount++;
+	if (!wowned)
+		PF_RULES_WUNLOCK();
+#endif
+
 	return (kif);
 }
 
 void
 pf_kkif_free(struct pfi_kkif *kif)
 {
+#ifdef PF_WANT_32_TO_64_COUNTER
+	bool wowned;
+#endif
+
 	if (! kif)
 		return;
 
+#ifdef PF_WANT_32_TO_64_COUNTER
+	wowned = PF_RULES_WOWNED();
+	if (!wowned)
+		PF_RULES_WLOCK();
+	LIST_REMOVE(kif, pfik_allkiflist);
+	V_pf_allkifcount--;
+	if (!wowned)
+		PF_RULES_WUNLOCK();
+#endif
+
 	for (int i = 0; i < 2; i++) {
 		for (int j = 0; j < 2; j++) {
 			for (int k = 0; k < 2; k++) {
-				counter_u64_free(kif->pfik_packets[i][j][k]);
-				counter_u64_free(kif->pfik_bytes[i][j][k]);
+				pf_counter_u64_deinit(&kif->pfik_packets[i][j][k]);
+				pf_counter_u64_deinit(&kif->pfik_bytes[i][j][k]);
 			}
 		}
 	}
@@ -248,8 +280,8 @@ pf_kkif_zero(struct pfi_kkif *kif)
 	for (int i = 0; i < 2; i++) {
 		for (int j = 0; j < 2; j++) {
 			for (int k = 0; k < 2; k++) {
-				counter_u64_zero(kif->pfik_packets[i][j][k]);
-				counter_u64_zero(kif->pfik_bytes[i][j][k]);
+				pf_counter_u64_zero(&kif->pfik_packets[i][j][k]);
+				pf_counter_u64_zero(&kif->pfik_bytes[i][j][k]);
 			}
 		}
 	}
@@ -791,15 +823,15 @@ pfi_update_status(const char *name, struct pf_status *pfs)
 			for (j = 0; j < 2; j++)
 				for (k = 0; k < 2; k++) {
 					pfs->pcounters[i][j][k] +=
-					    counter_u64_fetch(p->pfik_packets[i][j][k]);
+					    pf_counter_u64_fetch(&p->pfik_packets[i][j][k]);
 					pfs->bcounters[i][j] +=
-					    counter_u64_fetch(p->pfik_bytes[i][j][k]);
+					    pf_counter_u64_fetch(&p->pfik_bytes[i][j][k]);
 				}
 	}
 }
 
 static void
-pf_kkif_to_kif(const struct pfi_kkif *kkif, struct pfi_kif *kif)
+pf_kkif_to_kif(struct pfi_kkif *kkif, struct pfi_kif *kif)
 {
 
 	bzero(kif, sizeof(*kif));
@@ -808,9 +840,9 @@ pf_kkif_to_kif(const struct pfi_kkif *kkif, struct pfi_kif *kif)
 		for (int j = 0; j < 2; j++) {
 			for (int k = 0; k < 2; k++) {
 				kif->pfik_packets[i][j][k] =
-				    counter_u64_fetch(kkif->pfik_packets[i][j][k]);
+				    pf_counter_u64_fetch(&kkif->pfik_packets[i][j][k]);
 				kif->pfik_bytes[i][j][k] =
-				    counter_u64_fetch(kkif->pfik_bytes[i][j][k]);
+				    pf_counter_u64_fetch(&kkif->pfik_bytes[i][j][k]);
 			}
 		}
 	}
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 1b2c329fdb2c..e02fff4f88f6 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -319,6 +319,13 @@ pfattach_vnet(void)
 	V_pf_default_rule.states_tot = counter_u64_alloc(M_WAITOK);
 	V_pf_default_rule.src_nodes = counter_u64_alloc(M_WAITOK);
 
+#ifdef PF_WANT_32_TO_64_COUNTER
+	V_pf_kifmarker = malloc(sizeof(*V_pf_kifmarker), PFI_MTYPE, M_WAITOK | M_ZERO);
+	PF_RULES_WLOCK();
+	LIST_INSERT_HEAD(&V_pf_allkiflist, V_pf_kifmarker, pfik_allkiflist);
+	PF_RULES_WUNLOCK();
+#endif
+
 	/* initialize default timeouts */
 	my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
 	my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
@@ -5601,6 +5608,16 @@ pf_unload_vnet(void)
 #endif
 	uma_zdestroy(V_pf_tag_z);
 
+#ifdef PF_WANT_32_TO_64_COUNTER
+	PF_RULES_WLOCK();
+	LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
+	PF_RULES_WUNLOCK();
+	free(V_pf_kifmarker, PFI_MTYPE);
+
+	MPASS(LIST_EMPTY(&V_pf_allkiflist));
+	MPASS(V_pf_allkifcount == 0);
+#endif
+
 	/* Free counters last as we updated them during shutdown. */
 	counter_u64_free(V_pf_default_rule.evaluations);
 	for (int i = 0; i < 2; i++) {


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