git: cd784bf4d001 - stable/14 - ip_mroute: Convert to using a regular mutex

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 16 Feb 2026 19:47:32 UTC
The branch stable/14 has been updated by markj:

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

commit cd784bf4d0010085cd029ed76d0a55b1c57a8e9e
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-01-27 14:58:02 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-02-16 16:09:28 +0000

    ip_mroute: Convert to using a regular mutex
    
    The multicast routing code was using spin mutexes for packet counting,
    but there is no reason to use them instead of regular mutexes, given
    that none of this code runs in an interrupt context.  Convert to using
    default mutexes.
    
    Reviewed by:    glebius
    MFC after:      2 weeks
    Sponsored by:   Stormshield
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D54603
    
    (cherry picked from commit a265c8b4a5a7c8fdd33e27b8f74bd2a514f82c70)
---
 sys/netinet/ip_mroute.c | 35 ++++++++++++++++++-----------------
 sys/netinet/ip_mroute.h | 10 +++++-----
 2 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 306335ff8b79..133269edf3ba 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -602,12 +602,12 @@ get_vif_cnt(struct sioc_vif_req *req)
 		return EINVAL;
 	}
 
-	mtx_lock_spin(&V_viftable[vifi].v_spin);
+	mtx_lock(&V_viftable[vifi].v_mtx);
 	req->icount = V_viftable[vifi].v_pkt_in;
 	req->ocount = V_viftable[vifi].v_pkt_out;
 	req->ibytes = V_viftable[vifi].v_bytes_in;
 	req->obytes = V_viftable[vifi].v_bytes_out;
-	mtx_unlock_spin(&V_viftable[vifi].v_spin);
+	mtx_unlock(&V_viftable[vifi].v_mtx);
 	MRW_RUNLOCK();
 
 	return 0;
@@ -985,8 +985,8 @@ add_vif(struct vifctl *vifcp)
 	vifp->v_pkt_out   = 0;
 	vifp->v_bytes_in  = 0;
 	vifp->v_bytes_out = 0;
-	sprintf(vifp->v_spin_name, "BM[%d] spin", vifcp->vifc_vifi);
-	mtx_init(&vifp->v_spin, vifp->v_spin_name, NULL, MTX_SPIN);
+	sprintf(vifp->v_mtx_name, "BM[%d] mtx", vifcp->vifc_vifi);
+	mtx_init(&vifp->v_mtx, vifp->v_mtx_name, NULL, MTX_DEF);
 
 	/* Adjust numvifs up if the vifi is higher than numvifs */
 	if (V_numvifs <= vifcp->vifc_vifi)
@@ -1034,7 +1034,7 @@ del_vif_locked(vifi_t vifi, struct ifnet **ifp_multi_leave, struct ifnet **ifp_f
 		}
 	}
 
-	mtx_destroy(&vifp->v_spin);
+	mtx_destroy(&vifp->v_mtx);
 
 	bzero((caddr_t)vifp, sizeof (*vifp));
 
@@ -1642,7 +1642,7 @@ ip_mdq(struct mbuf *m, struct ifnet *ifp, struct mfc *rt, vifi_t xmt_vif)
 	}
 
 	/* If I sourced this packet, it counts as output, else it was input. */
-	mtx_lock_spin(&V_viftable[vifi].v_spin);
+	mtx_lock(&V_viftable[vifi].v_mtx);
 	if (in_hosteq(ip->ip_src, V_viftable[vifi].v_lcl_addr)) {
 		V_viftable[vifi].v_pkt_out++;
 		V_viftable[vifi].v_bytes_out += plen;
@@ -1650,7 +1650,7 @@ ip_mdq(struct mbuf *m, struct ifnet *ifp, struct mfc *rt, vifi_t xmt_vif)
 		V_viftable[vifi].v_pkt_in++;
 		V_viftable[vifi].v_bytes_in += plen;
 	}
-	mtx_unlock_spin(&V_viftable[vifi].v_spin);
+	mtx_unlock(&V_viftable[vifi].v_mtx);
 
 	rt->mfc_pkt_cnt++;
 	rt->mfc_byte_cnt += plen;
@@ -1687,14 +1687,14 @@ ip_mdq(struct mbuf *m, struct ifnet *ifp, struct mfc *rt, vifi_t xmt_vif)
 		for (x = rt->mfc_bw_meter_leq; x != NULL; x = x->bm_mfc_next) {
 			/*
 			 * Record that a packet is received.
-			 * Spin lock has to be taken as callout context
+			 * A lock has to be taken as callout context
 			 * (expire_bw_meter_leq) might modify these fields
 			 * as well
 			 */
-			mtx_lock_spin(&x->bm_spin);
+			mtx_lock(&x->bm_mtx);
 			x->bm_measured.b_packets++;
 			x->bm_measured.b_bytes += plen;
-			mtx_unlock_spin(&x->bm_spin);
+			mtx_unlock(&x->bm_mtx);
 		}
 	}
 
@@ -1876,13 +1876,14 @@ expire_bw_meter_leq(void *arg)
 
 	/* Reset counters */
 	x->bm_start_time = now;
-	/* Spin lock has to be taken as ip_forward context
+	/*
+	 * The lock has to be taken as ip_forward context
 	 * might modify these fields as well
 	 */
-	mtx_lock_spin(&x->bm_spin);
+	mtx_lock(&x->bm_mtx);
 	x->bm_measured.b_bytes = 0;
 	x->bm_measured.b_packets = 0;
-	mtx_unlock_spin(&x->bm_spin);
+	mtx_unlock(&x->bm_mtx);
 
 	callout_schedule(&x->bm_meter_callout, tvtohz(&x->bm_threshold.b_time));
 
@@ -1968,8 +1969,8 @@ add_bw_upcall(struct bw_upcall *req)
 	x->bm_time_next = NULL;
 	x->bm_mfc = mfc;
 	x->arg = curvnet;
-	sprintf(x->bm_spin_name, "BM spin %p", x);
-	mtx_init(&x->bm_spin, x->bm_spin_name, NULL, MTX_SPIN);
+	sprintf(x->bm_mtx_name, "BM mtx %p", x);
+	mtx_init(&x->bm_mtx, x->bm_mtx_name, NULL, MTX_DEF);
 
 	/* For LEQ case create periodic callout */
 	if (req->bu_flags & BW_UPCALL_LEQ) {
@@ -1996,7 +1997,7 @@ free_bw_list(struct bw_meter *list)
 		/* MRW_WLOCK must be held here */
 		if (x->bm_flags & BW_METER_LEQ) {
 			callout_drain(&x->bm_meter_callout);
-			mtx_destroy(&x->bm_spin);
+			mtx_destroy(&x->bm_mtx);
 		}
 
 		list = list->bm_mfc_next;
@@ -2097,7 +2098,7 @@ bw_meter_geq_receive_packet(struct bw_meter *x, int plen, struct timeval *nowp)
 
 	/*
 	 * Processing for ">=" type of bw_meter entry.
-	 * bm_spin does not have to be hold here as in GEQ
+	 * bm_mtx does not have to be hold here as in GEQ
 	 * case this is the only context accessing bm_measured.
 	 */
 	if (BW_TIMEVALCMP(&delta, &x->bm_threshold.b_time, >)) {
diff --git a/sys/netinet/ip_mroute.h b/sys/netinet/ip_mroute.h
index aefc0933485b..52899a6e3c4e 100644
--- a/sys/netinet/ip_mroute.h
+++ b/sys/netinet/ip_mroute.h
@@ -264,9 +264,9 @@ struct vif {
     u_long		v_bytes_in;	/* # bytes in on interface	     */
     u_long		v_bytes_out;	/* # bytes out on interface	     */
 #ifdef _KERNEL
-#define	MROUTE_VIF_SYSCTL_LEN	__offsetof(struct vif, v_spin)
-    struct mtx		v_spin;		/* Spin mutex for pkt stats          */
-    char		v_spin_name[32];
+#define	MROUTE_VIF_SYSCTL_LEN	__offsetof(struct vif, v_mtx)
+    struct mtx		v_mtx;		/* mutex for pkt stats               */
+    char		v_mtx_name[32];
 #endif
 };
 
@@ -352,8 +352,8 @@ struct bw_meter {
 #ifdef _KERNEL
 	struct callout	bm_meter_callout;	/* Periodic callout          */
 	void*		arg;			/* custom argument           */
-	struct mtx 	bm_spin;		/* meter spin lock           */
-	char		bm_spin_name[32];
+	struct mtx 	bm_mtx;			/* meter lock                */
+	char		bm_mtx_name[32];
 #endif
 };