diff options
| author | riastradh <riastradh@NetBSD.org> | 2021-12-28 12:00:48 +0000 |
|---|---|---|
| committer | riastradh <riastradh@NetBSD.org> | 2021-12-28 12:00:48 +0000 |
| commit | fd9592dbac6f8ffd87c142f508504f62b8de0abf (patch) | |
| tree | 38ee2f0c3d009ecc22ea79095a8fc90d0e1fe1f2 /sys/dev | |
| parent | aa5037709d1340398c35a20e5111a902d8e7bf58 (diff) | |
mii(9): Fix callout race between mii_phy_down and mii_phy_detach.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/mii/mii_physubr.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c index 06925d5c96c..147b11cfcd4 100644 --- a/sys/dev/mii/mii_physubr.c +++ b/sys/dev/mii/mii_physubr.c @@ -1,4 +1,4 @@ -/* $NetBSD: mii_physubr.c,v 1.96 2021/12/15 08:28:22 msaitoh Exp $ */ +/* $NetBSD: mii_physubr.c,v 1.97 2021/12/28 12:00:48 riastradh Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.96 2021/12/15 08:28:22 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.97 2021/12/28 12:00:48 riastradh Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -429,8 +429,20 @@ mii_phy_down(struct mii_softc *sc) KASSERT(mii_locked(sc->mii_pdata)); if (sc->mii_flags & MIIF_DOINGAUTO) { - sc->mii_flags &= ~MIIF_DOINGAUTO; - callout_stop(&sc->mii_nway_ch); + /* + * Try to stop it. + * + * - If we stopped it before it expired, callout_stop + * returns 0, and it is our responsibility to clear + * MIIF_DOINGAUTO. + * + * - Otherwise, we're too late -- the callout has + * already begun, and we must leave MIIF_DOINGAUTO + * set so mii_phy_detach will wait for it to + * complete. + */ + if (!callout_stop(&sc->mii_nway_ch)) + sc->mii_flags &= ~MIIF_DOINGAUTO; } } |
