aboutsummaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2018-01-11 03:11:41 +0000
committerWarner Losh <imp@FreeBSD.org>2018-01-11 03:11:41 +0000
commit045f8bc8e4b096d8828d120d4e4a8f3bd39b9b73 (patch)
treef94611bd901146494bdae81f84f99b21763ab149 /sys/cam
parent776a2127efa4cf3e8cf65f98bb6cacaf0623ce8d (diff)
downloadsrc-045f8bc8e4b096d8828d120d4e4a8f3bd39b9b73.tar.gz
src-045f8bc8e4b096d8828d120d4e4a8f3bd39b9b73.zip
When we crash, we'll stop the scheduler before we call the
shutdown_post_sync event. For adashutdown, this causes problems because we need to poll for completion of the commands, but we're not yet officially dumping yet, so the code from r326964 assumed we could use the interrupt-driven commands rather than the polled ones. This lead to a hang. Prevent this by also checking to see if the scheduler is stopped to do the polling. Reported by: markj@ Sponsored by: Netflix Differential Review: https://reviews.freebsd.org/D13845
Notes
Notes: svn path=/head/; revision=327805
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/cam_periph.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index b9c3dcf76eea..6cb4583e92d8 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -1187,10 +1187,16 @@ cam_periph_runccb(union ccb *ccb,
* scheduler is running in this case, we still need to poll the I/O to
* avoid sleeping waiting for the ccb to complete.
*
- * XXX To avoid locking problems, dumping/polling callers must call
+ * A panic triggered dump stops the scheduler, any callback from the
+ * shutdown_post_sync event will run with the scheduler stopped, but
+ * before we're officially dumping. To avoid hanging in adashutdown
+ * initiated commands (or other similar situations), we have to test for
+ * either SCHEDULER_STOPPED() here as well.
+ *
+ * To avoid locking problems, dumping/polling callers must call
* without a periph lock held.
*/
- must_poll = dumping;
+ must_poll = dumping || SCHEDULER_STOPPED();
ccb->ccb_h.cbfcnp = cam_periph_done;
/*