Module Name: src Committed By: skrll Date: Sat Aug 10 12:16:47 UTC 2024
Modified Files: src/sys/arch/arm/altera: cycv_gmac.c src/sys/arch/arm/amlogic: meson_dwmac.c src/sys/arch/arm/rockchip: rk_gmac.c src/sys/arch/arm/sunxi: sunxi_gmac.c src/sys/dev/ic: dwc_gmac.c dwc_gmac_var.h Log Message: awge(4): MP improvements Remove the non-MP-safe scaffolding and make the locking less coarse. To generate a diff of this commit: cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/altera/cycv_gmac.c cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/amlogic/meson_dwmac.c cvs rdiff -u -r1.22 -r1.23 src/sys/arch/arm/rockchip/rk_gmac.c cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/sunxi/sunxi_gmac.c cvs rdiff -u -r1.92 -r1.93 src/sys/dev/ic/dwc_gmac.c cvs rdiff -u -r1.20 -r1.21 src/sys/dev/ic/dwc_gmac_var.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/altera/cycv_gmac.c diff -u src/sys/arch/arm/altera/cycv_gmac.c:1.6 src/sys/arch/arm/altera/cycv_gmac.c:1.7 --- src/sys/arch/arm/altera/cycv_gmac.c:1.6 Fri Jan 29 14:12:01 2021 +++ src/sys/arch/arm/altera/cycv_gmac.c Sat Aug 10 12:16:46 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: cycv_gmac.c,v 1.6 2021/01/29 14:12:01 skrll Exp $ */ +/* $NetBSD: cycv_gmac.c,v 1.7 2024/08/10 12:16:46 skrll Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -30,7 +30,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cycv_gmac.c,v 1.6 2021/01/29 14:12:01 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cycv_gmac.c,v 1.7 2024/08/10 12:16:46 skrll Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -132,7 +132,7 @@ cycv_gmac_attach(device_t parent, device aprint_naive("\n"); aprint_normal(": GMAC\n"); - if (fdtbus_intr_establish_xname(phandle, 0, IPL_NET, DWCGMAC_FDT_INTR_MPSAFE, + if (fdtbus_intr_establish_xname(phandle, 0, IPL_NET, FDT_INTR_MPSAFE, cycv_gmac_intr, sc, device_xname(sc->sc_dev)) == NULL) { aprint_error_dev(self, "failed to establish interrupt on %s\n", intrstr); Index: src/sys/arch/arm/amlogic/meson_dwmac.c diff -u src/sys/arch/arm/amlogic/meson_dwmac.c:1.14 src/sys/arch/arm/amlogic/meson_dwmac.c:1.15 --- src/sys/arch/arm/amlogic/meson_dwmac.c:1.14 Fri Nov 19 07:04:27 2021 +++ src/sys/arch/arm/amlogic/meson_dwmac.c Sat Aug 10 12:16:46 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: meson_dwmac.c,v 1.14 2021/11/19 07:04:27 jdc Exp $ */ +/* $NetBSD: meson_dwmac.c,v 1.15 2024/08/10 12:16:46 skrll Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -28,7 +28,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: meson_dwmac.c,v 1.14 2021/11/19 07:04:27 jdc Exp $"); +__KERNEL_RCSID(0, "$NetBSD: meson_dwmac.c,v 1.15 2024/08/10 12:16:46 skrll Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -266,7 +266,7 @@ meson_dwmac_attach(device_t parent, devi aprint_normal(": Gigabit Ethernet Controller\n"); if (fdtbus_intr_establish_xname(phandle, 0, IPL_NET, - DWCGMAC_FDT_INTR_MPSAFE, meson_dwmac_intr, sc, + FDT_INTR_MPSAFE, meson_dwmac_intr, sc, device_xname(sc->sc_dev)) == NULL) { aprint_error_dev(self, "failed to establish interrupt on %s\n", intrstr); return; Index: src/sys/arch/arm/rockchip/rk_gmac.c diff -u src/sys/arch/arm/rockchip/rk_gmac.c:1.22 src/sys/arch/arm/rockchip/rk_gmac.c:1.23 --- src/sys/arch/arm/rockchip/rk_gmac.c:1.22 Sun Dec 31 09:45:58 2023 +++ src/sys/arch/arm/rockchip/rk_gmac.c Sat Aug 10 12:16:46 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: rk_gmac.c,v 1.22 2023/12/31 09:45:58 skrll Exp $ */ +/* $NetBSD: rk_gmac.c,v 1.23 2024/08/10 12:16:46 skrll Exp $ */ /*- * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca> @@ -28,7 +28,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rk_gmac.c,v 1.22 2023/12/31 09:45:58 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rk_gmac.c,v 1.23 2024/08/10 12:16:46 skrll Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -551,7 +551,7 @@ rk_gmac_attach(device_t parent, device_t return; if (fdtbus_intr_establish_xname(phandle, 0, IPL_NET, - DWCGMAC_FDT_INTR_MPSAFE, rk_gmac_intr, sc, + FDT_INTR_MPSAFE, rk_gmac_intr, sc, device_xname(self)) == NULL) { aprint_error_dev(self, "failed to establish interrupt on %s\n", intrstr); return; Index: src/sys/arch/arm/sunxi/sunxi_gmac.c diff -u src/sys/arch/arm/sunxi/sunxi_gmac.c:1.10 src/sys/arch/arm/sunxi/sunxi_gmac.c:1.11 --- src/sys/arch/arm/sunxi/sunxi_gmac.c:1.10 Sun Nov 7 19:21:33 2021 +++ src/sys/arch/arm/sunxi/sunxi_gmac.c Sat Aug 10 12:16:47 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_gmac.c,v 1.10 2021/11/07 19:21:33 jmcneill Exp $ */ +/* $NetBSD: sunxi_gmac.c,v 1.11 2024/08/10 12:16:47 skrll Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -28,7 +28,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_gmac.c,v 1.10 2021/11/07 19:21:33 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_gmac.c,v 1.11 2024/08/10 12:16:47 skrll Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -201,7 +201,7 @@ sunxi_gmac_attach(device_t parent, devic aprint_normal(": GMAC\n"); if (fdtbus_intr_establish_xname(phandle, 0, IPL_NET, - DWCGMAC_FDT_INTR_MPSAFE, sunxi_gmac_intr, sc, + FDT_INTR_MPSAFE, sunxi_gmac_intr, sc, device_xname(self)) == NULL) { aprint_error_dev(self, "failed to establish interrupt on %s\n", intrstr); return; Index: src/sys/dev/ic/dwc_gmac.c diff -u src/sys/dev/ic/dwc_gmac.c:1.92 src/sys/dev/ic/dwc_gmac.c:1.93 --- src/sys/dev/ic/dwc_gmac.c:1.92 Sat Aug 10 12:11:14 2024 +++ src/sys/dev/ic/dwc_gmac.c Sat Aug 10 12:16:47 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_gmac.c,v 1.92 2024/08/10 12:11:14 skrll Exp $ */ +/* $NetBSD: dwc_gmac.c,v 1.93 2024/08/10 12:16:47 skrll Exp $ */ /*- * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.92 2024/08/10 12:11:14 skrll Exp $"); +__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.93 2024/08/10 12:16:47 skrll Exp $"); /* #define DWC_GMAC_DEBUG 1 */ @@ -294,7 +294,11 @@ dwc_gmac_attach(struct dwc_gmac_softc *s goto fail; } - sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); + sc->sc_stopping = false; + sc->sc_txbusy = false; + + sc->sc_core_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); + sc->sc_intr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); mutex_init(&sc->sc_txq.t_mtx, MUTEX_DEFAULT, IPL_NET); mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET); @@ -304,9 +308,7 @@ dwc_gmac_attach(struct dwc_gmac_softc *s ifp->if_softc = sc; strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; -#ifdef DWCGMAC_MPSAFE ifp->if_extflags = IFEF_MPSAFE; -#endif ifp->if_ioctl = dwc_gmac_ioctl; ifp->if_start = dwc_gmac_start; ifp->if_init = dwc_gmac_init; @@ -355,12 +357,12 @@ dwc_gmac_attach(struct dwc_gmac_softc *s /* * Enable interrupts */ - mutex_enter(sc->sc_lock); + mutex_enter(sc->sc_intr_lock); bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK, AWIN_DEF_MAC_INTRMASK); bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE, GMAC_DEF_DMA_INT_MASK); - mutex_exit(sc->sc_lock); + mutex_exit(sc->sc_intr_lock); return 0; @@ -862,9 +864,11 @@ dwc_gmac_init(struct ifnet *ifp) { struct dwc_gmac_softc * const sc = ifp->if_softc; - mutex_enter(sc->sc_lock); + KASSERT(IFNET_LOCKED(ifp)); + + mutex_enter(sc->sc_core_lock); int ret = dwc_gmac_init_locked(ifp); - mutex_exit(sc->sc_lock); + mutex_exit(sc->sc_core_lock); return ret; } @@ -875,8 +879,10 @@ dwc_gmac_init_locked(struct ifnet *ifp) struct dwc_gmac_softc * const sc = ifp->if_softc; uint32_t ffilt; - if (ifp->if_flags & IFF_RUNNING) - return 0; + ASSERT_SLEEPABLE(); + KASSERT(IFNET_LOCKED(ifp)); + KASSERT(mutex_owned(sc->sc_core_lock)); + KASSERT(ifp == &sc->sc_ec.ec_if); dwc_gmac_stop_locked(ifp, 0); @@ -931,10 +937,16 @@ dwc_gmac_init_locked(struct ifnet *ifp) "setting DMA opmode register: %08x\n", opmode); #endif + ifp->if_flags |= IFF_RUNNING; + sc->sc_if_flags = ifp->if_flags; + + mutex_enter(sc->sc_intr_lock); sc->sc_stopping = false; - ifp->if_flags |= IFF_RUNNING; + mutex_enter(&sc->sc_txq.t_mtx); sc->sc_txbusy = false; + mutex_exit(&sc->sc_txq.t_mtx); + mutex_exit(sc->sc_intr_lock); return 0; } @@ -943,17 +955,13 @@ static void dwc_gmac_start(struct ifnet *ifp) { struct dwc_gmac_softc * const sc = ifp->if_softc; -#ifdef DWCGMAC_MPSAFE KASSERT(if_is_mpsafe(ifp)); -#endif - mutex_enter(sc->sc_lock); + mutex_enter(sc->sc_intr_lock); if (!sc->sc_stopping) { - mutex_enter(&sc->sc_txq.t_mtx); dwc_gmac_start_locked(ifp); - mutex_exit(&sc->sc_txq.t_mtx); } - mutex_exit(sc->sc_lock); + mutex_exit(sc->sc_intr_lock); } static void @@ -964,10 +972,13 @@ dwc_gmac_start_locked(struct ifnet *ifp) int start = sc->sc_txq.t_cur; struct mbuf *m0; - if ((ifp->if_flags & IFF_RUNNING) == 0) - return; - if (sc->sc_txbusy) + KASSERT(mutex_owned(sc->sc_intr_lock)); + + mutex_enter(&sc->sc_txq.t_mtx); + if (sc->sc_txbusy) { + mutex_exit(&sc->sc_txq.t_mtx); return; + } for (;;) { IFQ_POLL(&ifp->if_snd, m0); @@ -996,6 +1007,7 @@ dwc_gmac_start_locked(struct ifnet *ifp) bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TXPOLL, ~0U); } + mutex_exit(&sc->sc_txq.t_mtx); } static void @@ -1003,9 +1015,9 @@ dwc_gmac_stop(struct ifnet *ifp, int dis { struct dwc_gmac_softc * const sc = ifp->if_softc; - mutex_enter(sc->sc_lock); + mutex_enter(sc->sc_core_lock); dwc_gmac_stop_locked(ifp, disable); - mutex_exit(sc->sc_lock); + mutex_exit(sc->sc_core_lock); } static void @@ -1013,8 +1025,19 @@ dwc_gmac_stop_locked(struct ifnet *ifp, { struct dwc_gmac_softc * const sc = ifp->if_softc; + ASSERT_SLEEPABLE(); + KASSERT(IFNET_LOCKED(ifp)); + KASSERT(mutex_owned(sc->sc_core_lock)); + + mutex_enter(sc->sc_intr_lock); sc->sc_stopping = true; + mutex_enter(&sc->sc_txq.t_mtx); + sc->sc_txbusy = false; + mutex_exit(&sc->sc_txq.t_mtx); + + mutex_exit(sc->sc_intr_lock); + bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE, bus_space_read_4(sc->sc_bst, sc->sc_bsh, @@ -1030,7 +1053,7 @@ dwc_gmac_stop_locked(struct ifnet *ifp, dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq); ifp->if_flags &= ~IFF_RUNNING; - sc->sc_txbusy = false; + sc->sc_if_flags = ifp->if_flags; } /* @@ -1126,19 +1149,19 @@ dwc_gmac_ifflags_cb(struct ethercom *ec) struct dwc_gmac_softc * const sc = ifp->if_softc; int ret = 0; - mutex_enter(sc->sc_lock); + KASSERT(IFNET_LOCKED(ifp)); + mutex_enter(sc->sc_core_lock); + u_short change = ifp->if_flags ^ sc->sc_if_flags; sc->sc_if_flags = ifp->if_flags; if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) { ret = ENETRESET; - goto out; - } - if ((change & IFF_PROMISC) != 0) { + } else if ((change & IFF_PROMISC) != 0) { dwc_gmac_setmulti(sc); } -out: - mutex_exit(sc->sc_lock); + + mutex_exit(sc->sc_core_lock); return ret; } @@ -1149,37 +1172,33 @@ dwc_gmac_ioctl(struct ifnet *ifp, u_long struct dwc_gmac_softc * const sc = ifp->if_softc; int error = 0; - int s = splnet(); - error = ether_ioctl(ifp, cmd, data); + switch (cmd) { + case SIOCADDMULTI: + case SIOCDELMULTI: + break; + default: + KASSERT(IFNET_LOCKED(ifp)); + } -#ifdef DWCGMAC_MPSAFE + const int s = splnet(); + error = ether_ioctl(ifp, cmd, data); splx(s); -#endif if (error == ENETRESET) { error = 0; - if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI) - ; - else if (ifp->if_flags & IFF_RUNNING) { - /* - * Multicast list has changed; set the hardware filter - * accordingly. - */ - mutex_enter(sc->sc_lock); - dwc_gmac_setmulti(sc); - mutex_exit(sc->sc_lock); + if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI) { + mutex_enter(sc->sc_core_lock); + if (sc->sc_if_flags & IFF_RUNNING) { + /* + * Multicast list has changed; set the hardware + * filter accordingly. + */ + dwc_gmac_setmulti(sc); + } + mutex_exit(sc->sc_core_lock); } } - /* Try to get things going again */ - if (ifp->if_flags & IFF_UP) - dwc_gmac_start(ifp); - sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; - -#ifndef DWCGMAC_MPSAFE - splx(s); -#endif - return error; } @@ -1382,11 +1401,11 @@ dwc_gmac_setmulti(struct dwc_gmac_softc uint32_t ffilt, h; int mcnt; - KASSERT(mutex_owned(sc->sc_lock)); + KASSERT(mutex_owned(sc->sc_core_lock)); ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); - if (ifp->if_flags & IFF_PROMISC) { + if (sc->sc_if_flags & IFF_PROMISC) { ffilt |= AWIN_GMAC_MAC_FFILT_PR; goto special_filter; } @@ -1427,7 +1446,6 @@ dwc_gmac_setmulti(struct dwc_gmac_softc hashes[0]); bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, hashes[1]); - sc->sc_if_flags = ifp->if_flags; #ifdef DWC_GMAC_DEBUG dwc_gmac_dump_ffilt(sc, ffilt); @@ -1445,7 +1463,7 @@ special_filter: 0xffffffff); bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0xffffffff); - sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; + sc->sc_if_flags = ifp->if_flags; } int @@ -1454,8 +1472,11 @@ dwc_gmac_intr(struct dwc_gmac_softc *sc) uint32_t status, dma_status; int rv = 0; - if (sc->sc_stopping) + mutex_enter(sc->sc_intr_lock); + if (sc->sc_stopping) { + mutex_exit(sc->sc_intr_lock); return 0; + } status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR); if (status & AWIN_GMAC_MII_IRQ) { @@ -1500,6 +1521,8 @@ dwc_gmac_intr(struct dwc_gmac_softc *sc) if (rv) if_schedule_deferred_start(&sc->sc_ec.ec_if); + mutex_exit(sc->sc_intr_lock); + return rv; } Index: src/sys/dev/ic/dwc_gmac_var.h diff -u src/sys/dev/ic/dwc_gmac_var.h:1.20 src/sys/dev/ic/dwc_gmac_var.h:1.21 --- src/sys/dev/ic/dwc_gmac_var.h:1.20 Thu Aug 8 06:44:19 2024 +++ src/sys/dev/ic/dwc_gmac_var.h Sat Aug 10 12:16:47 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_gmac_var.h,v 1.20 2024/08/08 06:44:19 skrll Exp $ */ +/* $NetBSD: dwc_gmac_var.h,v 1.21 2024/08/10 12:16:47 skrll Exp $ */ /*- * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. @@ -29,21 +29,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifdef _KERNEL_OPT -#include "opt_net_mpsafe.h" -#endif - -/* Use DWCGMAC_MPSAFE inside the front-ends for interrupt handlers. */ -#ifdef NET_MPSAFE -#define DWCGMAC_MPSAFE 1 -#endif - -#ifdef DWCGMAC_MPSAFE -#define DWCGMAC_FDT_INTR_MPSAFE FDT_INTR_MPSAFE -#else -#define DWCGMAC_FDT_INTR_MPSAFE 0 -#endif - /* * Rx and Tx Ring counts that map into single 4K page with 16byte descriptor * size. For Rx a full mbuf cluster is allocated for each which consumes @@ -122,7 +107,8 @@ struct dwc_gmac_softc { bool sc_txbusy; bool sc_stopping; krndsource_t rnd_source; - kmutex_t *sc_lock; /* lock for softc operations */ + kmutex_t *sc_core_lock; /* lock for softc operations */ + kmutex_t *sc_intr_lock; /* lock for interrupt operations */ struct if_percpuq *sc_ipq; /* softint-based input queues */