Module Name: src
Committed By: skrll
Date: Fri Oct 4 10:41:58 UTC 2024
Modified Files:
src/sys/dev/ic: bcmgenet.c bcmgenetvar.h
Log Message:
Fix a problem noted by Taylor...
touching if_flags is forbidden in this context (no IFNET_LOCK guaranteed)
sc_promisc should be cached when if_flags changes, not when
SIOCADDMULTI/SIOCDELMULTI runs
by caching if_flags in sc_if_flags via a ifflags_cb.
To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/ic/bcmgenet.c
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/ic/bcmgenetvar.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/dev/ic/bcmgenet.c
diff -u src/sys/dev/ic/bcmgenet.c:1.20 src/sys/dev/ic/bcmgenet.c:1.21
--- src/sys/dev/ic/bcmgenet.c:1.20 Sun Sep 15 07:38:08 2024
+++ src/sys/dev/ic/bcmgenet.c Fri Oct 4 10:41:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: bcmgenet.c,v 1.20 2024/09/15 07:38:08 skrll Exp $ */
+/* $NetBSD: bcmgenet.c,v 1.21 2024/10/04 10:41:58 skrll Exp $ */
/*-
* Copyright (c) 2020 Jared McNeill <[email protected]>
@@ -33,7 +33,7 @@
#include "opt_ddb.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcmgenet.c,v 1.20 2024/09/15 07:38:08 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcmgenet.c,v 1.21 2024/10/04 10:41:58 skrll Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -319,7 +319,7 @@ genet_tick(void *softc)
GENET_LOCK(sc);
mii_tick(mii);
- if (sc->sc_running)
+ if ((sc->sc_if_flags & IFF_RUNNING) != 0)
callout_schedule(&sc->sc_stat_ch, hz);
GENET_UNLOCK(sc);
}
@@ -570,7 +570,7 @@ genet_init_locked(struct genet_softc *sc
WR4(sc, GENET_UMAC_MAC1, val);
/* Setup RX filter */
- sc->sc_promisc = ifp->if_flags & IFF_PROMISC;
+ sc->sc_if_flags = ifp->if_flags;
genet_setup_rxfilter(sc);
/* Setup TX/RX rings */
@@ -588,8 +588,8 @@ genet_init_locked(struct genet_softc *sc
GENET_ASSERT_TXLOCKED(sc);
sc->sc_txrunning = true;
- sc->sc_running = true;
ifp->if_flags |= IFF_RUNNING;
+ sc->sc_if_flags |= IFF_RUNNING;
mii_mediachg(mii);
callout_schedule(&sc->sc_stat_ch, hz);
@@ -646,7 +646,6 @@ genet_stop_locked(struct genet_softc *sc
sc->sc_txrunning = false;
GENET_TXUNLOCK(sc);
- sc->sc_running = false;
callout_halt(&sc->sc_stat_ch, &sc->sc_lock);
mii_down(&sc->sc_mii);
@@ -683,6 +682,7 @@ genet_stop_locked(struct genet_softc *sc
for (i=0; i<TX_DESC_COUNT; ++i)
genet_free_txbuf(sc, i);
+ sc->sc_if_flags &= ~IFF_RUNNING;
ifp->if_flags &= ~IFF_RUNNING;
}
@@ -902,6 +902,14 @@ genet_ioctl(struct ifnet *ifp, u_long cm
struct genet_softc *sc = ifp->if_softc;
int error;
+ switch (cmd) {
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ break;
+ default:
+ KASSERT(IFNET_LOCKED(ifp));
+ }
+
const int s = splnet();
error = ether_ioctl(ifp, cmd, data);
splx(s);
@@ -915,14 +923,37 @@ genet_ioctl(struct ifnet *ifp, u_long cm
error = if_init(ifp);
else if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI) {
GENET_LOCK(sc);
- sc->sc_promisc = ifp->if_flags & IFF_PROMISC;
- if (sc->sc_running)
+ if ((sc->sc_if_flags & IFF_RUNNING) != 0)
genet_setup_rxfilter(sc);
GENET_UNLOCK(sc);
}
return error;
}
+static int
+genet_ifflags_cb(struct ethercom *ec)
+{
+ struct ifnet * const ifp = &ec->ec_if;
+ struct genet_softc * const sc = ifp->if_softc;
+ int ret = 0;
+
+ KASSERT(IFNET_LOCKED(ifp));
+ GENET_LOCK(sc);
+
+ 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;
+ } else if ((change & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
+ if ((sc->sc_if_flags & IFF_RUNNING) != 0)
+ genet_setup_rxfilter(sc);
+ }
+ GENET_UNLOCK(sc);
+
+ return ret;
+}
+
static void
genet_get_eaddr(struct genet_softc *sc, uint8_t *eaddr)
{
@@ -1116,6 +1147,8 @@ genet_attach(struct genet_softc *sc)
/* Attach ethernet interface */
ether_ifattach(ifp, eaddr);
+ ether_set_ifflags_cb(&sc->sc_ec, genet_ifflags_cb);
+
/* MBUFTRACE */
genet_claim_rxring(sc, GENET_DMA_DEFAULT_QUEUE);
Index: src/sys/dev/ic/bcmgenetvar.h
diff -u src/sys/dev/ic/bcmgenetvar.h:1.5 src/sys/dev/ic/bcmgenetvar.h:1.6
--- src/sys/dev/ic/bcmgenetvar.h:1.5 Sun Sep 15 07:38:08 2024
+++ src/sys/dev/ic/bcmgenetvar.h Fri Oct 4 10:41:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: bcmgenetvar.h,v 1.5 2024/09/15 07:38:08 skrll Exp $ */
+/* $NetBSD: bcmgenetvar.h,v 1.6 2024/10/04 10:41:58 skrll Exp $ */
/*-
* Copyright (c) 2020 Jared McNeill <[email protected]>
@@ -68,9 +68,8 @@ struct genet_softc {
kmutex_t sc_lock;
kmutex_t sc_txlock;
- bool sc_running;
+ u_short sc_if_flags;
bool sc_txrunning;
- bool sc_promisc;
struct genet_ring sc_tx;
struct genet_ring sc_rx;