When devices are invalidated, there's some cases where ccbs for that
device still wind up in xpt_done after the path has been invalidated. Since we don't always need sim or devq, add some guard rails to only fail if we have to use them. Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D14040
This commit is contained in:
parent
96e8c3c6da
commit
296548866a
@ -5374,8 +5374,8 @@ xpt_path_mtx(struct cam_path *path)
|
||||
static void
|
||||
xpt_done_process(struct ccb_hdr *ccb_h)
|
||||
{
|
||||
struct cam_sim *sim;
|
||||
struct cam_devq *devq;
|
||||
struct cam_sim *sim = NULL;
|
||||
struct cam_devq *devq = NULL;
|
||||
struct mtx *mtx = NULL;
|
||||
|
||||
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||
@ -5418,9 +5418,15 @@ xpt_done_process(struct ccb_hdr *ccb_h)
|
||||
mtx_unlock(&xsoftc.xpt_highpower_lock);
|
||||
}
|
||||
|
||||
sim = ccb_h->path->bus->sim;
|
||||
/*
|
||||
* Insulate against a race where the periph is destroyed
|
||||
* but CCBs are still not all processed.
|
||||
*/
|
||||
if (ccb_h->path->bus)
|
||||
sim = ccb_h->path->bus->sim;
|
||||
|
||||
if (ccb_h->status & CAM_RELEASE_SIMQ) {
|
||||
KASSERT(sim, ("sim missing for CAM_RELEASE_SIMQ request"));
|
||||
xpt_release_simq(sim, /*run_queue*/FALSE);
|
||||
ccb_h->status &= ~CAM_RELEASE_SIMQ;
|
||||
}
|
||||
@ -5431,10 +5437,13 @@ xpt_done_process(struct ccb_hdr *ccb_h)
|
||||
ccb_h->status &= ~CAM_DEV_QFRZN;
|
||||
}
|
||||
|
||||
devq = sim->devq;
|
||||
if ((ccb_h->func_code & XPT_FC_USER_CCB) == 0) {
|
||||
struct cam_ed *dev = ccb_h->path->device;
|
||||
|
||||
if (sim)
|
||||
devq = sim->devq;
|
||||
KASSERT(devq, ("sim missing for XPT_FC_USER_CCB request"));
|
||||
|
||||
mtx_lock(&devq->send_mtx);
|
||||
devq->send_active--;
|
||||
devq->send_openings++;
|
||||
|
Loading…
Reference in New Issue
Block a user