svn commit: r326964 - head/sys/cam

Warner Losh imp at FreeBSD.org
Tue Dec 19 04:13:23 UTC 2017


Author: imp
Date: Tue Dec 19 04:13:22 2017
New Revision: 326964
URL: https://svnweb.freebsd.org/changeset/base/326964

Log:
  When doing a dump, the scheduler is normally not running, so this
  changed worked to capture dumps for me. However, the test for
  SCHEDULER_STOPPED() isn't right. We can also call the dump routine
  from ddb, in which case the scheduler is still running. This leads to
  an assertion panic that we're sleeping when we shouldn't. Instead, use
  the proper test for dumping or not. This brings us in line with other
  places that do special things while we're doing polled I/O like this.
  
  Noticed by: pho@
  Differential Revision: https://reviews.freebsd.org/D13531

Modified:
  head/sys/cam/cam_periph.c

Modified: head/sys/cam/cam_periph.c
==============================================================================
--- head/sys/cam/cam_periph.c	Tue Dec 19 04:06:07 2017	(r326963)
+++ head/sys/cam/cam_periph.c	Tue Dec 19 04:13:22 2017	(r326964)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/kernel.h>
 #include <sys/bio.h>
+#include <sys/conf.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/buf.h>
@@ -1158,7 +1159,7 @@ cam_periph_runccb(union ccb *ccb,
 	struct bintime *starttime;
 	struct bintime ltime;
 	int error;
-	bool sched_stopped;
+	bool must_poll;
 	struct mtx *periph_mtx;
 	struct cam_periph *periph;
 	uint32_t timeout = 1;
@@ -1182,7 +1183,13 @@ cam_periph_runccb(union ccb *ccb,
 		devstat_start_transaction(ds, starttime);
 	}
 
-	sched_stopped = SCHEDULER_STOPPED();
+	/*
+	 * We must poll the I/O while we're dumping. The scheduler is normally
+	 * stopped for dumping, except when we call doadump from ddb. While the
+	 * scheduler is running in this case, we still need to poll the I/O to
+	 * avoid sleeping waiting for the ccb to complete.
+	 */
+	must_poll = dumping;
 	ccb->ccb_h.cbfcnp = cam_periph_done;
 	periph = xpt_path_periph(ccb->ccb_h.path);
 	periph_mtx = cam_periph_mtx(periph);
@@ -1193,7 +1200,7 @@ cam_periph_runccb(union ccb *ccb,
 	 * cam_periph_error can reschedule the ccb by calling xpt_action and returning
 	 * ERESTART, so we have to effect the polling in the do loop below.
 	 */
-	if (sched_stopped) {
+	if (must_poll) {
 		mtx_unlock(periph_mtx);
 		timeout = xpt_poll_setup(ccb);
 	}
@@ -1204,11 +1211,11 @@ cam_periph_runccb(union ccb *ccb,
 	} else {
 		xpt_action(ccb);
 		do {
-			if (!sched_stopped)
-				cam_periph_ccbwait(ccb);
-			else {
+			if (must_poll) {
 				xpt_pollwait(ccb, timeout);
 				timeout = ccb->ccb_h.timeout * 10;
+			} else {
+				cam_periph_ccbwait(ccb);
 			}
 			if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
 				error = 0;
@@ -1220,7 +1227,7 @@ cam_periph_runccb(union ccb *ccb,
 		} while (error == ERESTART);
 	}
 
-	if (sched_stopped)
+	if (must_poll)
 		mtx_lock(periph_mtx);
 
 	if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {


More information about the svn-src-head mailing list