git: 3f3e4f3c7472 - main - dummynet: don't use per-vnet locks to protect global data.

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Mon, 07 Feb 2022 22:00:24 UTC
The branch main has been updated by kp:

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

commit 3f3e4f3c7472640aab998612a2253da95102345a
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2022-01-27 10:41:21 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-02-07 21:59:46 +0000

    dummynet: don't use per-vnet locks to protect global data.
    
    The ref_count counter is global (i.e. not per-vnet) so we can't use a
    per-vnet lock to protect it. Moreover, in callouts curvnet is not set,
    so we'd end up panicing when trying to use DN_BH_WLOCK().
    
    Instead we use the global sched_lock, which is already used when
    evaluating ref_count (in unload_dn_aqm()).
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D34059
---
 sys/netpfil/ipfw/dn_aqm_pie.c      |  6 ++++--
 sys/netpfil/ipfw/dn_sched_fq_pie.c |  6 ++++--
 sys/netpfil/ipfw/ip_dn_private.h   |  2 ++
 sys/netpfil/ipfw/ip_dummynet.c     | 12 ++++++++++++
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/sys/netpfil/ipfw/dn_aqm_pie.c b/sys/netpfil/ipfw/dn_aqm_pie.c
index 5eadf08a4860..5079118a7f35 100644
--- a/sys/netpfil/ipfw/dn_aqm_pie.c
+++ b/sys/netpfil/ipfw/dn_aqm_pie.c
@@ -597,8 +597,10 @@ aqm_pie_init(struct dn_queue *q)
 		}
 
 		pst = q->aqm_status;
+		dummynet_sched_lock();
 		/* increase reference count for PIE module */
 		pie_desc.ref_count++;
+		dummynet_sched_unlock();
 		
 		pst->pq = q;
 		pst->parms = pprms;
@@ -632,9 +634,9 @@ pie_callout_cleanup(void *x)
 	mtx_unlock(&pst->lock_mtx);
 	mtx_destroy(&pst->lock_mtx);
 	free(x, M_DUMMYNET);
-	DN_BH_WLOCK();
+	dummynet_sched_lock();
 	pie_desc.ref_count--;
-	DN_BH_WUNLOCK();
+	dummynet_sched_unlock();
 }
 
 /* 
diff --git a/sys/netpfil/ipfw/dn_sched_fq_pie.c b/sys/netpfil/ipfw/dn_sched_fq_pie.c
index f589614be436..7765cbd15788 100644
--- a/sys/netpfil/ipfw/dn_sched_fq_pie.c
+++ b/sys/netpfil/ipfw/dn_sched_fq_pie.c
@@ -581,7 +581,7 @@ fqpie_callout_cleanup(void *x)
 	mtx_destroy(&pst->lock_mtx);
 	psi_extra = q->psi_extra;
 
-	DN_BH_WLOCK();
+	dummynet_sched_lock();
 	psi_extra->nr_active_q--;
 
 	/* when all sub-queues are destroyed, free flows fq_pie extra vars memory */
@@ -590,7 +590,7 @@ fqpie_callout_cleanup(void *x)
 		free(psi_extra, M_DUMMYNET);
 		fq_pie_desc.ref_count--;
 	}
-	DN_BH_WUNLOCK();
+	dummynet_sched_unlock();
 }
 
 /* 
@@ -1061,7 +1061,9 @@ fq_pie_new_sched(struct dn_sch_inst *_si)
 		pie_init(&flows[i], schk);
 	}
 
+	dummynet_sched_lock();
 	fq_pie_desc.ref_count++;
+	dummynet_sched_unlock();
 
 	return 0;
 }
diff --git a/sys/netpfil/ipfw/ip_dn_private.h b/sys/netpfil/ipfw/ip_dn_private.h
index 25015fe02c2d..d7df31b85345 100644
--- a/sys/netpfil/ipfw/ip_dn_private.h
+++ b/sys/netpfil/ipfw/ip_dn_private.h
@@ -399,6 +399,8 @@ VNET_DECLARE(struct dn_parms, dn_cfg);
 #define V_dn_cfg	VNET(dn_cfg)
 
 int dummynet_io(struct mbuf **, struct ip_fw_args *);
+void dummynet_sched_lock(void);
+void dummynet_sched_unlock(void);
 void dummynet_task(void *context, int pending);
 void dn_reschedule(void);
 struct dn_pkt_tag * dn_tag_get(struct mbuf *m);
diff --git a/sys/netpfil/ipfw/ip_dummynet.c b/sys/netpfil/ipfw/ip_dummynet.c
index 0cd606bd56b2..46300b90007e 100644
--- a/sys/netpfil/ipfw/ip_dummynet.c
+++ b/sys/netpfil/ipfw/ip_dummynet.c
@@ -109,6 +109,18 @@ dummynet(void *arg)
 	taskqueue_enqueue(dn_tq, &dn_task);
 }
 
+void
+dummynet_sched_lock(void)
+{
+	mtx_lock(&sched_mtx);
+}
+
+void
+dummynet_sched_unlock(void)
+{
+	mtx_unlock(&sched_mtx);
+}
+
 void
 dn_reschedule(void)
 {