Module Name: src Committed By: thorpej Date: Thu Nov 16 05:02:23 UTC 2023
Modified Files: src/sys/altq [thorpej-ifq]: if_altq.h src/sys/net [thorpej-ifq]: if_bridge.c if_ethersubr.c if_vlan.c src/sys/net80211 [thorpej-ifq]: ieee80211_input.c Log Message: Clean up the locking protocol around altq_etherclassify(). It's no longer required to acquire KERNEL_LOCK *just* because ALTQ is compiled into the kernel; you only have to acquire it if ALTQ is enabled on the interface in question. To generate a diff of this commit: cvs rdiff -u -r1.16.4.1 -r1.16.4.1.2.1 src/sys/altq/if_altq.h cvs rdiff -u -r1.189.6.1 -r1.189.6.1.2.1 src/sys/net/if_bridge.c cvs rdiff -u -r1.326.2.1.2.1 -r1.326.2.1.2.2 src/sys/net/if_ethersubr.c cvs rdiff -u -r1.171.2.1 -r1.171.2.1.2.1 src/sys/net/if_vlan.c cvs rdiff -u -r1.117.4.1 -r1.117.4.1.2.1 src/sys/net80211/ieee80211_input.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/altq/if_altq.h diff -u src/sys/altq/if_altq.h:1.16.4.1 src/sys/altq/if_altq.h:1.16.4.1.2.1 --- src/sys/altq/if_altq.h:1.16.4.1 Sat Nov 11 13:16:30 2023 +++ src/sys/altq/if_altq.h Thu Nov 16 05:02:23 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_altq.h,v 1.16.4.1 2023/11/11 13:16:30 thorpej Exp $ */ +/* $NetBSD: if_altq.h,v 1.16.4.1.2.1 2023/11/16 05:02:23 thorpej Exp $ */ /* $KAME: if_altq.h,v 1.12 2005/04/13 03:44:25 suz Exp $ */ /* @@ -188,7 +188,7 @@ extern int altq_disable(struct ifaltq *) extern struct mbuf *tbr_dequeue(struct ifaltq *, int); extern int (*altq_input)(struct mbuf *, int); #if 1 /* ALTQ3_CLFIER_COMPAT */ -void altq_etherclassify(struct ifaltq *, struct mbuf *); +void altq_etherclassify(struct ifqueue *, struct mbuf *); #endif #endif /* _KERNEL */ Index: src/sys/net/if_bridge.c diff -u src/sys/net/if_bridge.c:1.189.6.1 src/sys/net/if_bridge.c:1.189.6.1.2.1 --- src/sys/net/if_bridge.c:1.189.6.1 Sat Nov 11 13:16:30 2023 +++ src/sys/net/if_bridge.c Thu Nov 16 05:02:23 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bridge.c,v 1.189.6.1 2023/11/11 13:16:30 thorpej Exp $ */ +/* $NetBSD: if_bridge.c,v 1.189.6.1.2.1 2023/11/16 05:02:23 thorpej Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -80,7 +80,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.189.6.1 2023/11/11 13:16:30 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.189.6.1.2.1 2023/11/16 05:02:23 thorpej Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1488,18 +1488,18 @@ bridge_enqueue(struct bridge_softc *sc, } #ifdef ALTQ - KERNEL_LOCK(1, NULL); /* * If ALTQ is enabled on the member interface, do * classification; the queueing discipline might * not require classification, but might require * the address family/header pointer in the pktattr. */ + mutex_enter(dst_ifp->if_snd.ifq_lock); if (ALTQ_IS_ENABLED(&dst_ifp->if_snd)) { /* XXX IFT_ETHER */ - altq_etherclassify(dst_ifp->if_snd.ifq_altq, m); + altq_etherclassify(&dst_ifp->if_snd, m); } - KERNEL_UNLOCK_ONE(NULL); + mutex_exit(dst_ifp->if_snd.ifq_lock); #endif /* ALTQ */ if (vlan_has_tag(m) && Index: src/sys/net/if_ethersubr.c diff -u src/sys/net/if_ethersubr.c:1.326.2.1.2.1 src/sys/net/if_ethersubr.c:1.326.2.1.2.2 --- src/sys/net/if_ethersubr.c:1.326.2.1.2.1 Wed Nov 15 02:08:34 2023 +++ src/sys/net/if_ethersubr.c Thu Nov 16 05:02:23 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_ethersubr.c,v 1.326.2.1.2.1 2023/11/15 02:08:34 thorpej Exp $ */ +/* $NetBSD: if_ethersubr.c,v 1.326.2.1.2.2 2023/11/16 05:02:23 thorpej Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.326.2.1.2.1 2023/11/15 02:08:34 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.326.2.1.2.2 2023/11/16 05:02:23 thorpej Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -447,16 +447,16 @@ ether_output(struct ifnet * const ifp0, #endif #ifdef ALTQ - KERNEL_LOCK(1, NULL); /* * If ALTQ is enabled on the parent interface, do * classification; the queueing discipline might not * require classification, but might require the * address family/header pointer in the pktattr. */ + mutex_enter(ifp->if_snd.ifq_lock); if (ALTQ_IS_ENABLED(&ifp->if_snd)) - altq_etherclassify(ifp->if_snd.ifq_altq, m); - KERNEL_UNLOCK_ONE(NULL); + altq_etherclassify(&ifp->if_snd, m); + mutex_exit(ifp->if_snd.ifq_lock); #endif return if_enqueue(ifp, m); @@ -477,8 +477,9 @@ bad: * is indeed contiguous, then to read the LLC and so on. */ void -altq_etherclassify(struct ifaltq *ifq, struct mbuf *m) +altq_etherclassify(struct ifqueue *ifq, struct mbuf *m) { + struct ifaltq *altq = ifq->ifq_altq; struct ether_header *eh; struct mbuf *mtop = m; uint16_t ether_type; @@ -487,6 +488,18 @@ altq_etherclassify(struct ifaltq *ifq, s KASSERT((mtop->m_flags & M_PKTHDR) != 0); + /* + * Release the ifqueue lock so that we can acquire the + * KERNEL_LOCK in the right order. + */ + mutex_exit(ifq->ifq_lock); + KERNEL_LOCK(1, NULL); + mutex_enter(ifq->ifq_lock); + + if (!ALTQ_IS_ENABLED(ifq)) { + goto bad; + } + hlen = ETHER_HDR_LEN; eh = mtod(m, struct ether_header *); @@ -552,7 +565,7 @@ altq_etherclassify(struct ifaltq *ifq, s if (ALTQ_NEEDS_CLASSIFY(ifq)) { mtop->m_pkthdr.pattr_class = - (*ifq->altq_classify)(ifq->altq_clfier, m, af); + (*altq->altq_classify)(altq->altq_clfier, m, af); } mtop->m_pkthdr.pattr_af = af; mtop->m_pkthdr.pattr_hdr = hdr; @@ -560,9 +573,11 @@ altq_etherclassify(struct ifaltq *ifq, s m->m_data -= hlen; m->m_len += hlen; + KERNEL_UNLOCK_ONE(NULL); return; bad: + KERNEL_UNLOCK_ONE(NULL); mtop->m_pkthdr.pattr_class = NULL; mtop->m_pkthdr.pattr_hdr = NULL; mtop->m_pkthdr.pattr_af = AF_UNSPEC; Index: src/sys/net/if_vlan.c diff -u src/sys/net/if_vlan.c:1.171.2.1 src/sys/net/if_vlan.c:1.171.2.1.2.1 --- src/sys/net/if_vlan.c:1.171.2.1 Sat Nov 11 13:16:30 2023 +++ src/sys/net/if_vlan.c Thu Nov 16 05:02:23 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_vlan.c,v 1.171.2.1 2023/11/11 13:16:30 thorpej Exp $ */ +/* $NetBSD: if_vlan.c,v 1.171.2.1.2.1 2023/11/16 05:02:23 thorpej Exp $ */ /* * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. @@ -78,7 +78,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.171.2.1 2023/11/11 13:16:30 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.171.2.1.2.1 2023/11/16 05:02:23 thorpej Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1275,23 +1275,19 @@ vlan_start(struct ifnet *ifp) #ifdef ALTQ /* - * KERNEL_LOCK is required for ALTQ even if NET_MPSAFE is - * defined. - */ - KERNEL_LOCK(1, NULL); - /* * If ALTQ is enabled on the parent interface, do * classification; the queueing discipline might * not require classification, but might require * the address family/header pointer in the pktattr. */ + mutex_enter(p->if_snd.ifq_lock); if (ALTQ_IS_ENABLED(&p->if_snd)) { KASSERT( p->if_type == IFT_ETHER || p->if_type == IFT_L2TP); - altq_etherclassify(p->if_snd.ifq_altq, m); + altq_etherclassify(&p->if_snd, m); } - KERNEL_UNLOCK_ONE(NULL); + mutex_exit(p->if_snd.ifq_lock); #endif /* ALTQ */ bpf_mtap(ifp, m, BPF_D_OUT); Index: src/sys/net80211/ieee80211_input.c diff -u src/sys/net80211/ieee80211_input.c:1.117.4.1 src/sys/net80211/ieee80211_input.c:1.117.4.1.2.1 --- src/sys/net80211/ieee80211_input.c:1.117.4.1 Sat Nov 11 13:16:31 2023 +++ src/sys/net80211/ieee80211_input.c Thu Nov 16 05:02:23 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: ieee80211_input.c,v 1.117.4.1 2023/11/11 13:16:31 thorpej Exp $ */ +/* $NetBSD: ieee80211_input.c,v 1.117.4.1.2.1 2023/11/16 05:02:23 thorpej Exp $ */ /* * Copyright (c) 2001 Atsushi Onoe @@ -37,7 +37,7 @@ __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $"); #endif #ifdef __NetBSD__ -__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.117.4.1 2023/11/11 13:16:31 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.117.4.1.2.1 2023/11/16 05:02:23 thorpej Exp $"); #endif #ifdef _KERNEL_OPT @@ -900,9 +900,11 @@ ieee80211_deliver_data(struct ieee80211c if (m1 != NULL) { int len; #ifdef ALTQ + mutex_enter(ifp->if_snd.ifq_lock); if (ALTQ_IS_ENABLED(&ifp->if_snd)) { - altq_etherclassify(ifp->if_snd.ifq_altq, m1); + altq_etherclassify(&ifp->if_snd, m1); } + mutex_exit(ifp->if_snd.ifq_lock); #endif len = m1->m_pkthdr.len; IFQ_ENQUEUE(&ifp->if_snd, m1, error);