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 */
 

Reply via email to