[Midnightbsd-cvs] src [8752] trunk/sys/cam: Fix a panic during CAM EDT traversal.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Sep 25 22:36:48 EDT 2016


Revision: 8752
          http://svnweb.midnightbsd.org/src/?rev=8752
Author:   laffer1
Date:     2016-09-25 22:36:48 -0400 (Sun, 25 Sep 2016)
Log Message:
-----------
Fix a panic during CAM EDT traversal.

Modified Paths:
--------------
    trunk/sys/cam/cam_periph.c
    trunk/sys/cam/cam_xpt.c

Modified: trunk/sys/cam/cam_periph.c
===================================================================
--- trunk/sys/cam/cam_periph.c	2016-09-26 02:36:09 UTC (rev 8751)
+++ trunk/sys/cam/cam_periph.c	2016-09-26 02:36:48 UTC (rev 8752)
@@ -615,6 +615,14 @@
 	}
 
 	/*
+	 * We need to set this flag before dropping the topology lock, to
+	 * let anyone who is traversing the list that this peripheral is
+	 * about to be freed, and there will be no more reference count
+	 * checks.
+	 */
+	periph->flags |= CAM_PERIPH_FREE;
+
+	/*
 	 * The peripheral destructor semantics dictate calling with only the
 	 * SIM mutex held.  Since it might sleep, it should not be called
 	 * with the topology lock held.

Modified: trunk/sys/cam/cam_xpt.c
===================================================================
--- trunk/sys/cam/cam_xpt.c	2016-09-26 02:36:09 UTC (rev 8751)
+++ trunk/sys/cam/cam_xpt.c	2016-09-26 02:36:48 UTC (rev 8752)
@@ -2178,8 +2178,8 @@
 		 * invalidated, but not peripherals that are scheduled to
 		 * be freed.  So instead of calling cam_periph_acquire(),
 		 * which will fail if the periph has been invalidated, we
-		 * just check for the free flag here.  If it is free, we
-		 * skip to the next periph.
+		 * just check for the free flag here.  If it is in the
+		 * process of being freed, we skip to the next periph.
 		 */
 		if (periph->flags & CAM_PERIPH_FREE) {
 			next_periph = SLIST_NEXT(periph, periph_links);
@@ -2192,16 +2192,9 @@
 		 */
 		periph->refcount++;
 
-		xpt_unlock_buses();
-
 		retval = tr_func(periph, arg);
 
 		/*
-		 * We need the lock for list traversal.
-		 */
-		xpt_lock_buses();
-
-		/*
 		 * Grab the next peripheral before we release this one, so
 		 * our next pointer is still valid.
 		 */
@@ -2283,11 +2276,6 @@
 		 */
 		periph->refcount++;
 
-		/*
-		 * XXX KDM we have the toplogy lock here, but in
-		 * xptperiphtraverse(), we drop it before calling the
-		 * traversal function.  Which is correct?
-		 */
 		retval = tr_func(periph, arg);
 
 		/*



More information about the Midnightbsd-cvs mailing list