aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/aac/aac.c
diff options
context:
space:
mode:
authorAttilio Rao <attilio@FreeBSD.org>2011-06-10 20:23:56 +0000
committerAttilio Rao <attilio@FreeBSD.org>2011-06-10 20:23:56 +0000
commit1bd320ec51ff7a8fd032492a782204d17ed54054 (patch)
treeb62cb35c26dfca82ddee797222d786f9d3d55a2f /sys/dev/aac/aac.c
parent1c3bf595840f0f84514093b1014b316a2900c308 (diff)
downloadsrc-1bd320ec51ff7a8fd032492a782204d17ed54054.tar.gz
src-1bd320ec51ff7a8fd032492a782204d17ed54054.zip
- Fix races on detach handling of AAC_IFFLAGS_* mask
- Fix races on setting AAC_AIFFLAGS_ALLOCFIBS - Remove some unused AAC_IFFLAGS_* bits. Please note that the kthread still makes a difference between the total mask and AAC_AIFFLAGS_ALLOCFIBS because more flags may be added in the future to aifflags. Sponsored by: Sandvine Incorporated Reported and reviewed by: emaste MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=222951
Diffstat (limited to 'sys/dev/aac/aac.c')
-rw-r--r--sys/dev/aac/aac.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index 53528fd5d7ff..45cfa023430c 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -661,6 +661,16 @@ aac_detach(device_t dev)
callout_drain(&sc->aac_daemontime);
+ mtx_lock(&sc->aac_io_lock);
+ while (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
+ sc->aifflags |= AAC_AIFFLAGS_EXIT;
+ wakeup(sc->aifthread);
+ msleep(sc->aac_dev, &sc->aac_io_lock, PUSER, "aacdch", 0);
+ }
+ mtx_unlock(&sc->aac_io_lock);
+ KASSERT((sc->aifflags & AAC_AIFFLAGS_RUNNING) == 0,
+ ("%s: invalid detach state", __func__));
+
/* Remove the child containers */
while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
error = device_delete_child(dev, co->co_disk);
@@ -679,15 +689,6 @@ aac_detach(device_t dev)
free(sim, M_AACBUF);
}
- if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
- sc->aifflags |= AAC_AIFFLAGS_EXIT;
- wakeup(sc->aifthread);
- tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz);
- }
-
- if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
- panic("Cannot shutdown AIF thread");
-
if ((error = aac_shutdown(dev)))
return(error);
@@ -1020,7 +1021,7 @@ aac_command_thread(struct aac_softc *sc)
/*
* First see if any FIBs need to be allocated. This needs
* to be called without the driver lock because contigmalloc
- * will grab Giant, and would result in an LOR.
+ * can sleep.
*/
if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
mtx_unlock(&sc->aac_io_lock);
@@ -1372,7 +1373,9 @@ aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
if ((cm = aac_dequeue_free(sc)) == NULL) {
if (sc->total_fibs < sc->aac_max_fibs) {
+ mtx_lock(&sc->aac_io_lock);
sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS;
+ mtx_unlock(&sc->aac_io_lock);
wakeup(sc->aifthread);
}
return (EBUSY);