Fix a couple of CTL locking issues and clean up some duplicated code.

ctl_frontend_cam_sim.c:	Coalesce cfcs_online() and cfcs_offline()
			into a single function since these were
			identical except for one line.

			Make sure we hold the SIM lock around path
			creation, and calling xpt_rescan().

scsi_ctl.c:		In ctlfe_onoffline(), make sure we hold the
			SIM lock around path creation and free
			calls, as well as xpt_action().

			In ctlfe_lun_enable(), hold the SIM lock
			around path and peripheral operations that
			require it.

Sponsored by:	Spectra Logic Corporation
MFC after:	1 week
This commit is contained in:
Kenneth D. Merry 2012-12-09 19:53:21 +00:00
parent b3c69eef25
commit 54f90e7783
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=244052
2 changed files with 31 additions and 37 deletions

View File

@ -275,7 +275,7 @@ cfcs_shutdown(void)
}
static void
cfcs_online(void *arg)
cfcs_onoffline(void *arg, int online)
{
struct cfcs_softc *softc;
union ccb *ccb;
@ -283,13 +283,12 @@ cfcs_online(void *arg)
softc = (struct cfcs_softc *)arg;
mtx_lock(&softc->lock);
softc->online = 1;
mtx_unlock(&softc->lock);
softc->online = online;
ccb = xpt_alloc_ccb_nowait();
if (ccb == NULL) {
printf("%s: unable to allocate CCB for rescan\n", __func__);
return;
goto bailout;
}
if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
@ -297,37 +296,24 @@ cfcs_online(void *arg)
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
printf("%s: can't allocate path for rescan\n", __func__);
xpt_free_ccb(ccb);
return;
goto bailout;
}
xpt_rescan(ccb);
bailout:
mtx_unlock(&softc->lock);
}
static void
cfcs_online(void *arg)
{
cfcs_onoffline(arg, /*online*/ 1);
}
static void
cfcs_offline(void *arg)
{
struct cfcs_softc *softc;
union ccb *ccb;
softc = (struct cfcs_softc *)arg;
mtx_lock(&softc->lock);
softc->online = 0;
mtx_unlock(&softc->lock);
ccb = xpt_alloc_ccb_nowait();
if (ccb == NULL) {
printf("%s: unable to allocate CCB for rescan\n", __func__);
return;
}
if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
cam_sim_path(softc->sim), CAM_TARGET_WILDCARD,
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
printf("%s: can't allocate path for rescan\n", __func__);
xpt_free_ccb(ccb);
return;
}
xpt_rescan(ccb);
cfcs_onoffline(arg, /*online*/ 0);
}
static int

View File

@ -1687,16 +1687,21 @@ ctlfe_onoffline(void *arg, int online)
set_wwnn = 0;
sim = bus_softc->sim;
CAM_SIM_LOCK(sim);
status = xpt_create_path(&path, /*periph*/ NULL, bus_softc->path_id,
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
if (status != CAM_REQ_CMP) {
printf("%s: unable to create path!\n", __func__);
CAM_SIM_UNLOCK(sim);
return;
}
CAM_SIM_UNLOCK(sim);
ccb = (union ccb *)malloc(sizeof(*ccb), M_TEMP, M_WAITOK | M_ZERO);
xpt_setup_ccb(&ccb->ccb_h, path, CAM_PRIORITY_NONE);
sim = xpt_path_sim(path);
/*
* Copan WWN format:
@ -1883,27 +1888,30 @@ ctlfe_lun_enable(void *arg, struct ctl_id targ_id, int lun_id)
bus_softc = (struct ctlfe_softc *)arg;
sim = bus_softc->sim;
status = xpt_create_path_unlocked(&path, /*periph*/ NULL,
bus_softc->path_id,
targ_id.id,
lun_id);
CAM_SIM_LOCK(sim);
status = xpt_create_path(&path, /*periph*/ NULL, bus_softc->path_id,
targ_id.id, lun_id);
/* XXX KDM need some way to return status to CTL here? */
if (status != CAM_REQ_CMP) {
printf("%s: could not create path, status %#x\n", __func__,
status);
CAM_SIM_UNLOCK(sim);
return (1);
}
CAM_SIM_UNLOCK(sim);
softc = malloc(sizeof(*softc), M_CTLFE, M_WAITOK | M_ZERO);
sim = xpt_path_sim(path);
mtx_lock(sim->mtx);
CAM_SIM_LOCK(sim);
periph = cam_periph_find(path, "ctl");
if (periph != NULL) {
/* We've already got a periph, no need to alloc a new one. */
xpt_free_path(path);
free(softc, M_CTLFE);
mtx_unlock(sim->mtx);
CAM_SIM_UNLOCK(sim);
return (0);
}
@ -1923,7 +1931,7 @@ ctlfe_lun_enable(void *arg, struct ctl_id targ_id, int lun_id)
xpt_free_path(path);
mtx_unlock(sim->mtx);
CAM_SIM_UNLOCK(sim);
return (0);
}