Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Remove unnecessary wait in ldbegindetach.
details: https://anonhg.NetBSD.org/src/rev/854d0323eb5a
branches: trunk
changeset: 936698:854d0323eb5a
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Aug 02 01:17:56 2020 +0000
description:
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.
diffstat:
sys/dev/ld.c | 53 ++++++++++++++++++++++++-----------------------
sys/dev/ldvar.h | 4 +-
sys/dev/sdmmc/ld_sdmmc.c | 28 +++++++++++++-----------
3 files changed, 44 insertions(+), 41 deletions(-)
diffs (170 lines):
diff -r bf40c236c7b0 -r 854d0323eb5a sys/dev/ld.c
--- a/sys/dev/ld.c Sun Aug 02 00:20:21 2020 +0000
+++ b/sys/dev/ld.c Sun Aug 02 01:17:56 2020 +0000
@@ -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 @@
ldbegindetach(struct ld_softc *sc, int flags)
{
struct dk_softc *dksc = &sc->sc_dksc;
- int rv = 0;
-
- if ((sc->sc_flags & LDF_ENABLED) == 0)
- return (0);
+ int error;
- rv = disk_begindetach(&dksc->sc_dkdev, ld_lastclose, dksc->sc_dev, flags);
-
- if (rv != 0)
- return rv;
+ /* If we never attached properly, no problem with detaching. */
+ if ((sc->sc_flags & LDF_ENABLED) == 0)
+ 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 @@
if ((sc->sc_flags & LDF_ENABLED) == 0)
return;
+ /* Wait for commands queued with the hardware to complete. */
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))
+ 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 @@
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
diff -r bf40c236c7b0 -r 854d0323eb5a sys/dev/ldvar.h
--- a/sys/dev/ldvar.h Sun Aug 02 00:20:21 2020 +0000
+++ b/sys/dev/ldvar.h Sun Aug 02 01:17:56 2020 +0000
@@ -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 @@
/* 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 */
diff -r bf40c236c7b0 -r 854d0323eb5a sys/dev/sdmmc/ld_sdmmc.c
--- a/sys/dev/sdmmc/ld_sdmmc.c Sun Aug 02 00:20:21 2020 +0000
+++ b/sys/dev/sdmmc/ld_sdmmc.c Sun Aug 02 01:17:56 2020 +0000
@@ -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 @@
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 @@
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));
Home |
Main Index |
Thread Index |
Old Index