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