diff options
author | Attilio Rao <attilio@FreeBSD.org> | 2011-06-10 20:23:56 +0000 |
---|---|---|
committer | Attilio Rao <attilio@FreeBSD.org> | 2011-06-10 20:23:56 +0000 |
commit | 1bd320ec51ff7a8fd032492a782204d17ed54054 (patch) | |
tree | b62cb35c26dfca82ddee797222d786f9d3d55a2f /sys/dev/aac/aac.c | |
parent | 1c3bf595840f0f84514093b1014b316a2900c308 (diff) | |
download | src-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.c | 23 |
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); |