Module Name: src Committed By: riastradh Date: Sun Aug 2 01:17:57 UTC 2020
Modified Files: src/sys/dev: ld.c ldvar.h src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Remove unnecessary wait in ldbegindetach. Like disk_begindetach, ldbegindetach only commits to detaching but doesn't wait for existing xfers to drain; it is up to the driver to abort them, once we are committed, and then ldenddetach to wait for them to drain. To generate a diff of this commit: cvs rdiff -u -r1.110 -r1.111 src/sys/dev/ld.c cvs rdiff -u -r1.33 -r1.34 src/sys/dev/ldvar.h cvs rdiff -u -r1.40 -r1.41 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld.c diff -u src/sys/dev/ld.c:1.110 src/sys/dev/ld.c:1.111 --- src/sys/dev/ld.c:1.110 Mon Apr 13 08:05:02 2020 +++ src/sys/dev/ld.c Sun Aug 2 01:17:56 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: ld.c,v 1.110 2020/04/13 08:05:02 maxv Exp $ */ +/* $NetBSD: ld.c,v 1.111 2020/08/02 01:17:56 riastradh Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.110 2020/04/13 08:05:02 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.111 2020/08/02 01:17:56 riastradh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -189,26 +189,25 @@ int ldbegindetach(struct ld_softc *sc, int flags) { struct dk_softc *dksc = &sc->sc_dksc; - int rv = 0; + int error; + /* If we never attached properly, no problem with detaching. */ if ((sc->sc_flags & LDF_ENABLED) == 0) - return (0); - - rv = disk_begindetach(&dksc->sc_dkdev, ld_lastclose, dksc->sc_dev, flags); - - if (rv != 0) - return rv; + return 0; - mutex_enter(&sc->sc_mutex); - sc->sc_maxqueuecnt = 0; + /* + * If the disk is still open, back out before we commit to + * detaching. + */ + error = disk_begindetach(&dksc->sc_dkdev, ld_lastclose, dksc->sc_dev, + flags); + if (error) + return error; - while (sc->sc_queuecnt > 0) { - sc->sc_flags |= LDF_DRAIN; - cv_wait(&sc->sc_drain, &sc->sc_mutex); - } - mutex_exit(&sc->sc_mutex); + /* We are now committed to detaching. Prevent new xfers. */ + ldadjqparam(sc, 0); - return (rv); + return 0; } void @@ -220,12 +219,17 @@ ldenddetach(struct ld_softc *sc) if ((sc->sc_flags & LDF_ENABLED) == 0) return; - mutex_enter(&sc->sc_mutex); - /* Wait for commands queued with the hardware to complete. */ - if (sc->sc_queuecnt != 0) { - if (cv_timedwait(&sc->sc_drain, &sc->sc_mutex, 30 * hz)) + mutex_enter(&sc->sc_mutex); + while (sc->sc_queuecnt > 0) { + if (cv_timedwait(&sc->sc_drain, &sc->sc_mutex, 30 * hz)) { + /* + * XXX This seems like a recipe for crashing on + * use after free... + */ printf("%s: not drained\n", dksc->sc_xname); + break; + } } mutex_exit(&sc->sc_mutex); @@ -467,10 +471,7 @@ lddone(struct ld_softc *sc, struct buf * mutex_enter(&sc->sc_mutex); if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) { - if ((sc->sc_flags & LDF_DRAIN) != 0) { - sc->sc_flags &= ~LDF_DRAIN; - cv_broadcast(&sc->sc_drain); - } + cv_broadcast(&sc->sc_drain); mutex_exit(&sc->sc_mutex); dk_start(dksc, NULL); } else Index: src/sys/dev/ldvar.h diff -u src/sys/dev/ldvar.h:1.33 src/sys/dev/ldvar.h:1.34 --- src/sys/dev/ldvar.h:1.33 Tue Mar 19 07:01:14 2019 +++ src/sys/dev/ldvar.h Sun Aug 2 01:17:56 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: ldvar.h,v 1.33 2019/03/19 07:01:14 mlelstv Exp $ */ +/* $NetBSD: ldvar.h,v 1.34 2020/08/02 01:17:56 riastradh Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ struct ld_softc { /* sc_flags */ #define LDF_ENABLED 0x001 /* device enabled */ -#define LDF_DRAIN 0x020 /* maxqueuecnt has changed; drain */ +#define LDF_UNUSED0 0x020 /* was LDF_DRAIN */ #define LDF_NO_RND 0x040 /* do not attach rnd source */ #define LDF_MPSAFE 0x080 /* backend is MPSAFE */ Index: src/sys/dev/sdmmc/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.40 src/sys/dev/sdmmc/ld_sdmmc.c:1.41 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.40 Wed Jul 22 17:18:10 2020 +++ src/sys/dev/sdmmc/ld_sdmmc.c Sun Aug 2 01:17:56 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.40 2020/07/22 17:18:10 riastradh Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.41 2020/08/02 01:17:56 riastradh Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.40 2020/07/22 17:18:10 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.41 2020/08/02 01:17:56 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -344,11 +344,20 @@ ld_sdmmc_detach(device_t dev, int flags) struct ld_sdmmc_softc *sc = device_private(dev); struct ld_softc *ld = &sc->sc_ld; struct ld_sdmmc_task *task; - int rv, i; + int error, i; /* - * Block new xfers, abort all pending tasks, and wait for all - * pending waiters to notice that we're gone. + * Block new xfers, or fail if the disk is still open and the + * detach isn't forced. After this point, we are committed to + * detaching. + */ + error = ldbegindetach(ld, flags); + if (error) + return error; + + /* + * Abort all pending tasks, and wait for all pending waiters to + * notice that we're gone. */ mutex_enter(&sc->sc_lock); sc->sc_dying = true; @@ -358,14 +367,7 @@ ld_sdmmc_detach(device_t dev, int flags) cv_wait(&sc->sc_cv, &sc->sc_lock); mutex_exit(&sc->sc_lock); - /* Do the ld detach dance. */ - if ((rv = ldbegindetach(ld, flags)) != 0) { - /* Detach failed -- back out. */ - mutex_enter(&sc->sc_lock); - sc->sc_dying = false; - mutex_exit(&sc->sc_lock); - return rv; - } + /* Done! Destroy the disk. */ ldenddetach(ld); KASSERT(TAILQ_EMPTY(&sc->sc_xferq));