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 <jmcne...@invisible.ca> @@ -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 <jmcne...@invisible.ca> @@ -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;