aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/cam_xpt.c
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2018-08-13 19:59:32 +0000
committerWarner Losh <imp@FreeBSD.org>2018-08-13 19:59:32 +0000
commit0cc28e3cd57ade3b52139ac0d3fd357d6e325074 (patch)
treea045ce2290a720744730fbf2b47dac8cc1f267ef /sys/cam/cam_xpt.c
parent408954013a12e3d6295cea80887bc7c34075803a (diff)
Create xpt_sim_poll and refactor a bit using it.
xpt_sim_poll takes the sim to poll as an argument. It will do the proper locking protocol, call the SIM polling routine, and then call camisr_runqueue to process completions on any CCBs the SIM's poll routine completed. It will be used during late shutdown when a SIM is waiting for CCBs it sent during shutdown to finish and the scheduler isn't running because we've panic'd. This sequence was used twice in cam_xpt, so refactor those to use this new function. Sponsored by: Netflix Differential Review: https://reviews.freebsd.org/D16663
Notes
Notes: svn path=/head/; revision=337723
Diffstat (limited to 'sys/cam/cam_xpt.c')
-rw-r--r--sys/cam/cam_xpt.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index a1b3016c7695..3ce61e7f6198 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -3198,6 +3198,25 @@ call_sim:
start_ccb->ccb_h.status));
}
+/*
+ * Call the sim poll routine to allow the sim to complete
+ * any inflight requests, then call camisr_runqueue to
+ * complete any CCB that the polling completed.
+ */
+void
+xpt_sim_poll(struct cam_sim *sim)
+{
+ struct mtx *mtx;
+
+ mtx = sim->mtx;
+ if (mtx)
+ mtx_lock(mtx);
+ (*(sim->sim_poll))(sim);
+ if (mtx)
+ mtx_unlock(mtx);
+ camisr_runqueue();
+}
+
uint32_t
xpt_poll_setup(union ccb *start_ccb)
{
@@ -3205,12 +3224,10 @@ xpt_poll_setup(union ccb *start_ccb)
struct cam_sim *sim;
struct cam_devq *devq;
struct cam_ed *dev;
- struct mtx *mtx;
timeout = start_ccb->ccb_h.timeout * 10;
sim = start_ccb->ccb_h.path->bus->sim;
devq = sim->devq;
- mtx = sim->mtx;
dev = start_ccb->ccb_h.path->device;
/*
@@ -3223,12 +3240,7 @@ xpt_poll_setup(union ccb *start_ccb)
(--timeout > 0)) {
mtx_unlock(&devq->send_mtx);
DELAY(100);
- if (mtx)
- mtx_lock(mtx);
- (*(sim->sim_poll))(sim);
- if (mtx)
- mtx_unlock(mtx);
- camisr_runqueue();
+ xpt_sim_poll(sim);
mtx_lock(&devq->send_mtx);
}
dev->ccbq.dev_openings++;
@@ -3240,19 +3252,9 @@ xpt_poll_setup(union ccb *start_ccb)
void
xpt_pollwait(union ccb *start_ccb, uint32_t timeout)
{
- struct cam_sim *sim;
- struct mtx *mtx;
-
- sim = start_ccb->ccb_h.path->bus->sim;
- mtx = sim->mtx;
while (--timeout > 0) {
- if (mtx)
- mtx_lock(mtx);
- (*(sim->sim_poll))(sim);
- if (mtx)
- mtx_unlock(mtx);
- camisr_runqueue();
+ xpt_sim_poll(start_ccb->ccb_h.path->bus->sim);
if ((start_ccb->ccb_h.status & CAM_STATUS_MASK)
!= CAM_REQ_INPROG)
break;