git: 2373bf2d1ece - stable/12 - pf: hoist the unlinked rules lock out of the mass rule removal loop

From: Mateusz Guzik <mjg_at_FreeBSD.org>
Date: Mon, 28 Mar 2022 11:37:59 UTC
The branch stable/12 has been updated by mjg:

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

commit 2373bf2d1ece15c678ae818fff28ecf394848ebb
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2022-02-28 10:39:02 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2022-03-28 11:37:42 +0000

    pf: hoist the unlinked rules lock out of the mass rule removal loop
    
    Reviewed by:    kp
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    
    (cherry picked from commit b163dcab27862f90e0108a73185945456cafd2f3)
---
 sys/netpfil/pf/pf_ioctl.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index ac99ac6d80bc..11be26ad9438 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -453,16 +453,26 @@ pf_empty_kpool(struct pf_kpalist *poola)
 }
 
 static void
-pf_unlink_rule(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
+pf_unlink_rule_locked(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
 {
 
 	PF_RULES_WASSERT();
+	PF_UNLNKDRULES_ASSERT();
 
 	TAILQ_REMOVE(rulequeue, rule, entries);
 
-	PF_UNLNKDRULES_LOCK();
 	rule->rule_ref |= PFRULE_REFS;
 	TAILQ_INSERT_TAIL(&V_pf_unlinked_rules, rule, entries);
+}
+
+static void
+pf_unlink_rule(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
+{
+
+	PF_RULES_WASSERT();
+
+	PF_UNLNKDRULES_LOCK();
+	pf_unlink_rule_locked(rulequeue, rule);
 	PF_UNLNKDRULES_UNLOCK();
 }
 
@@ -1145,8 +1155,10 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
 
 
 	/* Purge the old rule list. */
+	PF_UNLNKDRULES_LOCK();
 	while ((rule = TAILQ_FIRST(old_rules)) != NULL)
-		pf_unlink_rule(old_rules, rule);
+		pf_unlink_rule_locked(old_rules, rule);
+	PF_UNLNKDRULES_UNLOCK();
 	if (rs->rules[rs_num].inactive.ptr_array)
 		free(rs->rules[rs_num].inactive.ptr_array, M_TEMP);
 	rs->rules[rs_num].inactive.ptr_array = NULL;