svn commit: r225551 - stable/8/sys/dev/aac
Attilio Rao
attilio at FreeBSD.org
Wed Sep 14 10:27:23 UTC 2011
Author: attilio
Date: Wed Sep 14 10:27:23 2011
New Revision: 225551
URL: http://svn.freebsd.org/changeset/base/225551
Log:
MFC r222951:
Fix races in handling flags at detach time for FIBs.
Sponsored by: Sandvine Incorporated
Modified:
stable/8/sys/dev/aac/aac.c
stable/8/sys/dev/aac/aacvar.h
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
Modified: stable/8/sys/dev/aac/aac.c
==============================================================================
--- stable/8/sys/dev/aac/aac.c Wed Sep 14 08:27:19 2011 (r225550)
+++ stable/8/sys/dev/aac/aac.c Wed Sep 14 10:27:23 2011 (r225551)
@@ -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,
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);
Modified: stable/8/sys/dev/aac/aacvar.h
==============================================================================
--- stable/8/sys/dev/aac/aacvar.h Wed Sep 14 08:27:19 2011 (r225550)
+++ stable/8/sys/dev/aac/aacvar.h Wed Sep 14 10:27:23 2011 (r225551)
@@ -386,13 +386,12 @@ struct aac_softc
struct proc *aifthread;
int aifflags;
#define AAC_AIFFLAGS_RUNNING (1 << 0)
-#define AAC_AIFFLAGS_AIF (1 << 1)
+#define AAC_AIFFLAGS_UNUSED0 (1 << 1)
#define AAC_AIFFLAGS_EXIT (1 << 2)
#define AAC_AIFFLAGS_EXITED (1 << 3)
-#define AAC_AIFFLAGS_PRINTF (1 << 4)
+#define AAC_AIFFLAGS_UNUSED1 (1 << 4)
#define AAC_AIFFLAGS_ALLOCFIBS (1 << 5)
-#define AAC_AIFFLAGS_PENDING (AAC_AIFFLAGS_AIF | AAC_AIFFLAGS_PRINTF | \
- AAC_AIFFLAGS_ALLOCFIBS)
+#define AAC_AIFFLAGS_PENDING AAC_AIFFLAGS_ALLOCFIBS
u_int32_t flags;
#define AAC_FLAGS_PERC2QC (1 << 0)
#define AAC_FLAGS_ENABLE_CAM (1 << 1) /* No SCSI passthrough */
More information about the svn-src-all
mailing list