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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 */