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
This commit is contained in:
Warner Losh 2018-08-13 19:59:32 +00:00
parent 408954013a
commit 0cc28e3cd5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=337723
2 changed files with 22 additions and 19 deletions

View File

@ -3198,6 +3198,25 @@ xpt_action_default(union ccb *start_ccb)
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;

View File

@ -148,6 +148,7 @@ void xpt_release_path(struct cam_path *path);
const char * xpt_action_name(uint32_t action);
void xpt_pollwait(union ccb *start_ccb, uint32_t timeout);
uint32_t xpt_poll_setup(union ccb *start_ccb);
void xpt_sim_poll(struct cam_sim *sim);
/*
* Perform a path inquiry at the request priority. The bzero may be