svn commit: r254214 - in projects/camlock/sys/cam: . ata scsi
Alexander Motin
mav at FreeBSD.org
Sun Aug 11 10:54:19 UTC 2013
Author: mav
Date: Sun Aug 11 10:54:16 2013
New Revision: 254214
URL: http://svnweb.freebsd.org/changeset/base/254214
Log:
Introduce per-device mutex locks to protect all device and periph states.
Do not use congested SIM lock for anything except actually talking to SIM.
There are still rough edges around async delivery, missing locking for list
of LUNs, and targ and CTL are probably broken, but nevertheless my test
system booted, passed basic tests and can't wait for some preliminary
benchmarking. ;)
Modified:
projects/camlock/sys/cam/ata/ata_da.c
projects/camlock/sys/cam/ata/ata_xpt.c
projects/camlock/sys/cam/cam_periph.c
projects/camlock/sys/cam/cam_periph.h
projects/camlock/sys/cam/cam_xpt.c
projects/camlock/sys/cam/cam_xpt.h
projects/camlock/sys/cam/cam_xpt_internal.h
projects/camlock/sys/cam/scsi/scsi_cd.c
projects/camlock/sys/cam/scsi/scsi_ch.c
projects/camlock/sys/cam/scsi/scsi_da.c
projects/camlock/sys/cam/scsi/scsi_enc.c
projects/camlock/sys/cam/scsi/scsi_enc_ses.c
projects/camlock/sys/cam/scsi/scsi_pass.c
projects/camlock/sys/cam/scsi/scsi_sg.c
projects/camlock/sys/cam/scsi/scsi_targ_bh.c
projects/camlock/sys/cam/scsi/scsi_target.c
projects/camlock/sys/cam/scsi/scsi_xpt.c
Modified: projects/camlock/sys/cam/ata/ata_da.c
==============================================================================
--- projects/camlock/sys/cam/ata/ata_da.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/ata/ata_da.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -1334,7 +1334,7 @@ adaregister(struct cam_periph *periph, v
* Schedule a periodic event to occasionally send an
* ordered tag to a device.
*/
- callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0);
+ callout_init_mtx(&softc->sendordered_c, cam_periph_mtx(periph), 0);
callout_reset(&softc->sendordered_c,
(ada_default_timeout * hz) / ADA_ORDEREDTAG_INTERVAL,
adasendorderedtag, softc);
Modified: projects/camlock/sys/cam/ata/ata_xpt.c
==============================================================================
--- projects/camlock/sys/cam/ata/ata_xpt.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/ata/ata_xpt.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -1477,6 +1477,7 @@ ata_scan_lun(struct cam_periph *periph,
cam_status status;
struct cam_path *new_path;
struct cam_periph *old_periph;
+ int lock;
CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_scan_lun\n"));
@@ -1515,6 +1516,9 @@ ata_scan_lun(struct cam_periph *periph,
request_ccb->crcn.flags = flags;
}
+ lock = (xpt_path_owned(path) == 0);
+ if (lock)
+ xpt_path_lock(path);
if ((old_periph = cam_periph_find(path, "aprobe")) != NULL) {
if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) {
probe_softc *softc;
@@ -1541,6 +1545,8 @@ ata_scan_lun(struct cam_periph *periph,
xpt_done(request_ccb);
}
}
+ if (lock)
+ xpt_path_unlock(path);
}
static void
@@ -1696,15 +1702,8 @@ ata_dev_advinfo(union ccb *start_ccb)
start_ccb->ccb_h.status = CAM_REQ_CMP;
if (cdai->flags & CDAI_FLAG_STORE) {
- int owned;
-
- owned = mtx_owned(start_ccb->ccb_h.path->bus->sim->mtx);
- if (owned == 0)
- mtx_lock(start_ccb->ccb_h.path->bus->sim->mtx);
xpt_async(AC_ADVINFO_CHANGED, start_ccb->ccb_h.path,
(void *)(uintptr_t)cdai->buftype);
- if (owned == 0)
- mtx_unlock(start_ccb->ccb_h.path->bus->sim->mtx);
}
}
@@ -2014,7 +2013,7 @@ ata_announce_periph(struct cam_periph *p
u_int speed;
u_int mb;
- mtx_assert(periph->sim->mtx, MA_OWNED);
+ cam_periph_assert(periph, MA_OWNED);
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
Modified: projects/camlock/sys/cam/cam_periph.c
==============================================================================
--- projects/camlock/sys/cam/cam_periph.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/cam_periph.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -206,7 +206,6 @@ cam_periph_alloc(periph_ctor_t *periph_c
periph->refcount = 1; /* Dropped by invalidation. */
periph->sim = sim;
SLIST_INIT(&periph->ccb_list);
- mtx_init(&periph->periph_mtx, "CAM periph lock", NULL, MTX_DEF);
status = xpt_create_path(&path, periph, path_id, target_id, lun_id);
if (status != CAM_REQ_CMP)
goto failure;
@@ -299,7 +298,7 @@ cam_periph_find(struct cam_path *path, c
TAILQ_FOREACH(periph, &(*p_drv)->units, unit_links) {
if (xpt_path_comp(periph->path, path) == 0) {
xpt_unlock_buses();
- mtx_assert(periph->sim->mtx, MA_OWNED);
+ cam_periph_assert(periph, MA_OWNED);
return(periph);
}
}
@@ -380,7 +379,7 @@ void
cam_periph_release_locked_buses(struct cam_periph *periph)
{
- mtx_assert(periph->sim->mtx, MA_OWNED);
+ cam_periph_assert(periph, MA_OWNED);
KASSERT(periph->refcount >= 1, ("periph->refcount >= 1"));
if (--periph->refcount == 0)
camperiphfree(periph);
@@ -401,16 +400,16 @@ cam_periph_release_locked(struct cam_per
void
cam_periph_release(struct cam_periph *periph)
{
- struct cam_sim *sim;
+ struct mtx *mtx;
if (periph == NULL)
return;
- sim = periph->sim;
- mtx_assert(sim->mtx, MA_NOTOWNED);
- mtx_lock(sim->mtx);
+ cam_periph_assert(periph, MA_NOTOWNED);
+ mtx = cam_periph_mtx(periph);
+ mtx_lock(mtx);
cam_periph_release_locked(periph);
- mtx_unlock(sim->mtx);
+ mtx_unlock(mtx);
}
int
@@ -428,10 +427,10 @@ cam_periph_hold(struct cam_periph *perip
if (cam_periph_acquire(periph) != CAM_REQ_CMP)
return (ENXIO);
- mtx_assert(periph->sim->mtx, MA_OWNED);
+ cam_periph_assert(periph, MA_OWNED);
while ((periph->flags & CAM_PERIPH_LOCKED) != 0) {
periph->flags |= CAM_PERIPH_LOCK_WANTED;
- if ((error = mtx_sleep(periph, periph->sim->mtx, priority,
+ if ((error = cam_periph_sleep(periph, periph, priority,
"caplck", 0)) != 0) {
cam_periph_release_locked(periph);
return (error);
@@ -450,7 +449,7 @@ void
cam_periph_unhold(struct cam_periph *periph)
{
- mtx_assert(periph->sim->mtx, MA_OWNED);
+ cam_periph_assert(periph, MA_OWNED);
periph->flags &= ~CAM_PERIPH_LOCKED;
if ((periph->flags & CAM_PERIPH_LOCK_WANTED) != 0) {
@@ -578,7 +577,7 @@ void
cam_periph_invalidate(struct cam_periph *periph)
{
- mtx_assert(periph->sim->mtx, MA_OWNED);
+ cam_periph_assert(periph, MA_OWNED);
/*
* We only call this routine the first time a peripheral is
* invalidated.
@@ -599,7 +598,7 @@ camperiphfree(struct cam_periph *periph)
{
struct periph_driver **p_drv;
- mtx_assert(periph->sim->mtx, MA_OWNED);
+ cam_periph_assert(periph, MA_OWNED);
for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) {
if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0)
break;
@@ -676,7 +675,6 @@ camperiphfree(struct cam_periph *periph)
periph->path, arg);
}
xpt_free_path(periph->path);
- mtx_destroy(&periph->periph_mtx);
free(periph, M_CAMPERIPH);
xpt_lock_buses();
}
@@ -947,12 +945,11 @@ cam_periph_unmapmem(union ccb *ccb, stru
void
cam_periph_ccbwait(union ccb *ccb)
{
- struct cam_sim *sim;
- sim = xpt_path_sim(ccb->ccb_h.path);
if ((ccb->ccb_h.pinfo.index != CAM_UNQUEUED_INDEX)
|| ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG))
- mtx_sleep(&ccb->ccb_h.cbfcnp, sim->mtx, PRIBIO, "cbwait", 0);
+ xpt_path_sleep(ccb->ccb_h.path, &ccb->ccb_h.cbfcnp, PRIBIO,
+ "cbwait", 0);
}
int
@@ -1033,12 +1030,10 @@ cam_periph_runccb(union ccb *ccb,
cam_flags camflags, u_int32_t sense_flags,
struct devstat *ds)
{
- struct cam_sim *sim;
int error;
error = 0;
- sim = xpt_path_sim(ccb->ccb_h.path);
- mtx_assert(sim->mtx, MA_OWNED);
+ xpt_path_assert(ccb->ccb_h.path, MA_OWNED);
/*
* If the user has supplied a stats structure, and if we understand
Modified: projects/camlock/sys/cam/cam_periph.h
==============================================================================
--- projects/camlock/sys/cam/cam_periph.h Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/cam_periph.h Sun Aug 11 10:54:16 2013 (r254214)
@@ -130,7 +130,6 @@ struct cam_periph {
TAILQ_ENTRY(cam_periph) unit_links;
ac_callback_t *deferred_callback;
ac_code deferred_ac;
- struct mtx periph_mtx;
};
#define CAM_PERIPH_MAXMAPS 2
@@ -190,26 +189,38 @@ int cam_periph_error(union ccb *ccb, ca
static __inline void
cam_periph_lock(struct cam_periph *periph)
{
- mtx_lock(periph->sim->mtx);
+ xpt_path_lock(periph->path);
}
static __inline void
cam_periph_unlock(struct cam_periph *periph)
{
- mtx_unlock(periph->sim->mtx);
+ xpt_path_unlock(periph->path);
}
static __inline int
cam_periph_owned(struct cam_periph *periph)
{
- return (mtx_owned(periph->sim->mtx));
+ return (xpt_path_owned(periph->path));
+}
+
+static __inline void
+cam_periph_assert(struct cam_periph *periph, int what)
+{
+ mtx_assert(xpt_path_mtx(periph->path), what);
}
static __inline int
cam_periph_sleep(struct cam_periph *periph, void *chan, int priority,
const char *wmesg, int timo)
{
- return (msleep(chan, periph->sim->mtx, priority, wmesg, timo));
+ return (xpt_path_sleep(periph->path, chan, priority, wmesg, timo));
+}
+
+static __inline struct mtx *
+cam_periph_mtx(struct cam_periph *periph)
+{
+ return (xpt_path_mtx(periph->path));
}
static inline struct cam_periph *
@@ -232,7 +243,7 @@ cam_periph_acquire_next(struct cam_perip
{
struct cam_periph *periph = pperiph;
- mtx_assert(pperiph->sim->mtx, MA_NOTOWNED);
+ cam_periph_assert(pperiph, MA_NOTOWNED);
xpt_lock_buses();
do {
periph = TAILQ_NEXT(periph, unit_links);
Modified: projects/camlock/sys/cam/cam_xpt.c
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/cam_xpt.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -117,6 +117,7 @@ struct xpt_softc {
struct mtx xpt_topo_lock;
struct mtx xpt_lock;
+ struct taskqueue *xpt_taskq;
};
typedef enum {
@@ -450,8 +451,6 @@ xptdoioctl(struct cdev *dev, u_long cmd,
ccb = xpt_alloc_ccb();
- CAM_SIM_LOCK(bus->sim);
-
/*
* Create a path using the bus, target, and lun the
* user passed in.
@@ -470,11 +469,12 @@ xptdoioctl(struct cdev *dev, u_long cmd,
xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path,
inccb->ccb_h.pinfo.priority);
xpt_merge_ccb(ccb, inccb);
+ xpt_path_lock(ccb->ccb_h.path);
cam_periph_runccb(ccb, NULL, 0, 0, NULL);
+ xpt_path_unlock(ccb->ccb_h.path);
bcopy(ccb, inccb, sizeof(union ccb));
xpt_free_path(ccb->ccb_h.path);
xpt_free_ccb(ccb);
- CAM_SIM_UNLOCK(bus->sim);
break;
case XPT_DEBUG: {
@@ -485,8 +485,6 @@ xptdoioctl(struct cdev *dev, u_long cmd,
* allocate it on the stack.
*/
- CAM_SIM_LOCK(bus->sim);
-
/*
* Create a path using the bus, target, and lun the
* user passed in.
@@ -507,7 +505,6 @@ xptdoioctl(struct cdev *dev, u_long cmd,
xpt_action(&ccb);
bcopy(&ccb, inccb, sizeof(union ccb));
xpt_free_path(ccb.ccb_h.path);
- CAM_SIM_UNLOCK(bus->sim);
break;
}
@@ -555,9 +552,7 @@ xptdoioctl(struct cdev *dev, u_long cmd,
/*
* This is an immediate CCB, we can send it on directly.
*/
- CAM_SIM_LOCK(xpt_path_sim(xpt_periph->path));
xpt_action(inccb);
- CAM_SIM_UNLOCK(xpt_path_sim(xpt_periph->path));
/*
* Map the buffers back into user space.
@@ -775,7 +770,6 @@ static void
xpt_scanner_thread(void *dummy)
{
union ccb *ccb;
- struct cam_sim *sim;
xpt_lock_buses();
for (;;) {
@@ -786,10 +780,7 @@ xpt_scanner_thread(void *dummy)
TAILQ_REMOVE(&xsoftc.ccb_scanq, &ccb->ccb_h, sim_links.tqe);
xpt_unlock_buses();
- sim = ccb->ccb_h.path->bus->sim;
- CAM_SIM_LOCK(sim);
xpt_action(ccb);
- CAM_SIM_UNLOCK(sim);
xpt_lock_buses();
}
@@ -858,6 +849,8 @@ xpt_init(void *dummy)
mtx_init(&cam_simq_lock, "CAM SIMQ lock", NULL, MTX_DEF);
mtx_init(&xsoftc.xpt_lock, "XPT lock", NULL, MTX_DEF);
mtx_init(&xsoftc.xpt_topo_lock, "XPT topology lock", NULL, MTX_DEF);
+ xsoftc.xpt_taskq = taskqueue_create("CAM XPT task", M_WAITOK,
+ taskqueue_thread_enqueue, /*context*/&xsoftc.xpt_taskq);
#ifdef CAM_BOOT_DELAY
/*
@@ -1001,7 +994,7 @@ xpt_announce_periph(struct cam_periph *p
{
struct cam_path *path = periph->path;
- mtx_assert(periph->sim->mtx, MA_OWNED);
+ cam_periph_assert(periph, MA_OWNED);
printf("%s%d at %s%d bus %d scbus%d target %d lun %d\n",
periph->periph_name, periph->unit_number,
@@ -1057,7 +1050,7 @@ xpt_getattr(char *buf, size_t len, const
struct ccb_dev_advinfo cdai;
struct scsi_vpd_id_descriptor *idd;
- mtx_assert(path->bus->sim->mtx, MA_OWNED);
+ xpt_path_assert(path, MA_OWNED);
memset(&cdai, 0, sizeof(cdai));
xpt_setup_ccb(&cdai.ccb_h, path, CAM_PRIORITY_NORMAL);
@@ -2026,9 +2019,7 @@ xptbustraverse(struct cam_eb *start_bus,
xpt_unlock_buses();
}
for (; bus != NULL; bus = next_bus) {
- CAM_SIM_LOCK(bus->sim);
retval = tr_func(bus, arg);
- CAM_SIM_UNLOCK(bus->sim);
if (retval == 0) {
xpt_release_bus(bus);
break;
@@ -2102,7 +2093,9 @@ xptdevicetraverse(struct cam_et *target,
mtx_unlock(&bus->eb_mtx);
}
for (; device != NULL; device = next_device) {
+ mtx_lock(&device->device_mtx);
retval = tr_func(device, arg);
+ mtx_unlock(&device->device_mtx);
if (retval == 0) {
xpt_release_device(device);
break;
@@ -2200,7 +2193,6 @@ xptpdperiphtraverse(struct periph_driver
xpt_periphfunc_t *tr_func, void *arg)
{
struct cam_periph *periph, *next_periph;
- struct cam_sim *sim;
int retval;
retval = 1;
@@ -2220,10 +2212,9 @@ xptpdperiphtraverse(struct periph_driver
xpt_unlock_buses();
}
for (; periph != NULL; periph = next_periph) {
- sim = periph->sim;
- CAM_SIM_LOCK(sim);
+ cam_periph_lock(periph);
retval = tr_func(periph, arg);
- CAM_SIM_UNLOCK(sim);
+ cam_periph_unlock(periph);
if (retval == 0) {
cam_periph_release(periph);
break;
@@ -2409,6 +2400,7 @@ xpt_action_default(union ccb *start_ccb)
{
struct cam_path *path;
struct cam_sim *sim;
+ int lock;
path = start_ccb->ccb_h.path;
CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_action_default\n"));
@@ -2562,7 +2554,12 @@ xpt_action_default(union ccb *start_ccb)
case XPT_PATH_INQ:
call_sim:
sim = path->bus->sim;
+ lock = (mtx_owned(sim->mtx) == 0);
+ if (lock)
+ CAM_SIM_LOCK(sim);
(*(sim->sim_action))(sim, start_ccb);
+ if (lock)
+ CAM_SIM_UNLOCK(sim);
break;
case XPT_PATH_STATS:
start_ccb->cpis.last_reset = path->bus->last_reset;
@@ -2725,11 +2722,6 @@ call_sim:
position_type = CAM_DEV_POS_PDRV;
}
- /*
- * Note that we drop the SIM lock here, because the EDT
- * traversal code needs to do its own locking.
- */
- CAM_SIM_UNLOCK(xpt_path_sim(cdm->ccb_h.path));
switch(position_type & CAM_DEV_POS_TYPEMASK) {
case CAM_DEV_POS_EDT:
xptedtmatch(cdm);
@@ -2741,7 +2733,6 @@ call_sim:
cdm->status = CAM_DEV_MATCH_ERROR;
break;
}
- CAM_SIM_LOCK(xpt_path_sim(cdm->ccb_h.path));
if (cdm->status == CAM_DEV_MATCH_ERROR)
start_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
@@ -2891,7 +2882,6 @@ call_sim:
}
case XPT_DEBUG: {
struct cam_path *oldpath;
- struct cam_sim *oldsim;
/* Check that all request bits are supported. */
if (start_ccb->cdbg.flags & ~(CAM_DEBUG_COMPILE)) {
@@ -2901,15 +2891,9 @@ call_sim:
cam_dflags = CAM_DEBUG_NONE;
if (cam_dpath != NULL) {
- /* To release the old path we must hold proper lock. */
oldpath = cam_dpath;
cam_dpath = NULL;
- oldsim = xpt_path_sim(oldpath);
- CAM_SIM_UNLOCK(xpt_path_sim(start_ccb->ccb_h.path));
- CAM_SIM_LOCK(oldsim);
xpt_free_path(oldpath);
- CAM_SIM_UNLOCK(oldsim);
- CAM_SIM_LOCK(xpt_path_sim(start_ccb->ccb_h.path));
}
if (start_ccb->cdbg.flags != CAM_DEBUG_NONE) {
if (xpt_create_path(&cam_dpath, NULL,
@@ -3567,11 +3551,6 @@ xpt_path_string(struct cam_path *path, c
{
struct sbuf sb;
-#ifdef INVARIANTS
- if (path != NULL && path->bus != NULL)
- mtx_assert(path->bus->sim->mtx, MA_OWNED);
-#endif
-
sbuf_new(&sb, str, str_len, 0);
if (path == NULL)
@@ -3639,8 +3618,8 @@ xpt_path_sim(struct cam_path *path)
struct cam_periph*
xpt_path_periph(struct cam_path *path)
{
- mtx_assert(path->bus->sim->mtx, MA_OWNED);
+ xpt_path_assert(path, MA_OWNED);
return (path->periph);
}
@@ -3989,7 +3968,7 @@ xpt_async_process(struct cam_periph *per
path = ccb->ccb_h.path;
async_code = ccb->casync.async_code;
async_arg = ccb->casync.async_arg_ptr;
- mtx_assert(path->bus->sim->mtx, MA_OWNED);
+// mtx_assert(path->bus->sim->mtx, MA_OWNED);
CAM_DEBUG(path, CAM_DEBUG_TRACE | CAM_DEBUG_INFO,
("xpt_async(%s)\n", xpt_async_string(async_code)));
@@ -4535,6 +4514,16 @@ xpt_alloc_device_default(struct cam_eb *
return (device);
}
+static void
+xpt_destroy_device(void *context, int pending)
+{
+ struct cam_ed *device = context;
+
+ mtx_lock(&device->device_mtx);
+ mtx_destroy(&device->device_mtx);
+ free(device, M_CAMDEV);
+}
+
struct cam_ed *
xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
{
@@ -4579,7 +4568,9 @@ xpt_alloc_device(struct cam_eb *bus, str
device->tag_delay_count = 0;
device->tag_saved_openings = 0;
device->refcount = 1;
+ mtx_init(&device->device_mtx, "CAM device lock", NULL, MTX_DEF);
callout_init_mtx(&device->callout, bus->sim->mtx, 0);
+ TASK_INIT(&device->device_destroy_task, 0, xpt_destroy_device, device);
/*
* Hold a reference to our parent bus so it
* will not go away before we do.
@@ -4651,7 +4642,7 @@ xpt_release_device(struct cam_ed *device
free(device->physpath, M_CAMXPT);
free(device->rcap_buf, M_CAMXPT);
free(device->serial_num, M_CAMXPT);
- free(device, M_CAMDEV);
+ taskqueue_enqueue(xsoftc.xpt_taskq, &device->device_destroy_task);
}
u_int32_t
@@ -5004,6 +4995,49 @@ xpt_assert_buses(int what)
mtx_assert(&xsoftc.xpt_topo_lock, what);
}
+void
+xpt_path_lock(struct cam_path *path)
+{
+
+ mtx_lock(&path->device->device_mtx);
+}
+
+void
+xpt_path_unlock(struct cam_path *path)
+{
+
+ mtx_unlock(&path->device->device_mtx);
+}
+
+void
+xpt_path_assert(struct cam_path *path, int what)
+{
+
+ mtx_assert(&path->device->device_mtx, what);
+}
+
+int
+xpt_path_owned(struct cam_path *path)
+{
+
+ return (mtx_owned(&path->device->device_mtx));
+}
+
+int
+xpt_path_sleep(struct cam_path *path, void *chan, int priority,
+ const char *wmesg, int timo)
+{
+
+ return (msleep(chan, &path->device->device_mtx, priority, wmesg, timo));
+}
+
+struct mtx *
+xpt_path_mtx(struct cam_path *path)
+{
+
+ return (&path->device->device_mtx);
+}
+
static void
camisr(void *dummy)
{
@@ -5029,6 +5063,7 @@ static void
camisr_runqueue(struct cam_sim *sim)
{
struct ccb_hdr *ccb_h;
+ struct mtx *mtx;
mtx_lock(&sim->sim_doneq_mtx);
while ((ccb_h = TAILQ_FIRST(&sim->sim_doneq)) != NULL) {
@@ -5069,6 +5104,9 @@ camisr_runqueue(struct cam_sim *sim)
mtx_unlock(&xsoftc.xpt_lock);
}
+ mtx = xpt_path_mtx(ccb_h->path);
+ mtx_lock(mtx);
+
if ((ccb_h->func_code & XPT_FC_USER_CCB) == 0) {
struct cam_ed *dev;
@@ -5098,11 +5136,8 @@ camisr_runqueue(struct cam_sim *sim)
mtx_unlock(&sim->devq->send_mtx);
if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
- && (--dev->tag_delay_count == 0)) {
- CAM_SIM_LOCK(sim);
+ && (--dev->tag_delay_count == 0))
xpt_start_tags(ccb_h->path);
- CAM_SIM_UNLOCK(sim);
- }
}
if (ccb_h->status & CAM_RELEASE_SIMQ) {
@@ -5118,9 +5153,8 @@ camisr_runqueue(struct cam_sim *sim)
}
/* Call the peripheral driver's callback */
- CAM_SIM_LOCK(sim);
(*ccb_h->cbfcnp)(ccb_h->path->periph, (union ccb *)ccb_h);
- CAM_SIM_UNLOCK(sim);
+ mtx_unlock(mtx);
mtx_lock(&sim->sim_doneq_mtx);
}
sim->sim_doneq_flags &= ~CAM_SIM_DQ_ONQ;
Modified: projects/camlock/sys/cam/cam_xpt.h
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.h Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/cam_xpt.h Sun Aug 11 10:54:16 2013 (r254214)
@@ -103,6 +103,14 @@ void xpt_release_boot(void);
void xpt_lock_buses(void);
void xpt_unlock_buses(void);
void xpt_assert_buses(int what);
+void xpt_path_lock(struct cam_path *path);
+void xpt_path_unlock(struct cam_path *path);
+void xpt_path_assert(struct cam_path *path, int what);
+int xpt_path_owned(struct cam_path *path);
+int xpt_path_sleep(struct cam_path *path, void *chan,
+ int priority, const char *wmesg,
+ int timo);
+struct mtx * xpt_path_mtx(struct cam_path *path);
cam_status xpt_register_async(int event, ac_callback_t *cbfunc,
void *cbarg, struct cam_path *path);
cam_status xpt_compile_path(struct cam_path *new_path,
Modified: projects/camlock/sys/cam/cam_xpt_internal.h
==============================================================================
--- projects/camlock/sys/cam/cam_xpt_internal.h Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/cam_xpt_internal.h Sun Aug 11 10:54:16 2013 (r254214)
@@ -29,6 +29,8 @@
#ifndef _CAM_CAM_XPT_INTERNAL_H
#define _CAM_CAM_XPT_INTERNAL_H 1
+#include <sys/taskqueue.h>
+
/* Forward Declarations */
struct cam_eb;
struct cam_et;
@@ -125,6 +127,8 @@ struct cam_ed {
u_int32_t refcount;
struct callout callout;
STAILQ_ENTRY(cam_ed) highpowerq_entry;
+ struct mtx device_mtx;
+ struct task device_destroy_task;
};
/*
Modified: projects/camlock/sys/cam/scsi/scsi_cd.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_cd.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/scsi/scsi_cd.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -982,9 +982,9 @@ cdregister(struct cam_periph *periph, vo
STAILQ_INIT(&nchanger->chluns);
callout_init_mtx(&nchanger->long_handle,
- periph->sim->mtx, 0);
+ cam_periph_mtx(periph), 0);
callout_init_mtx(&nchanger->short_handle,
- periph->sim->mtx, 0);
+ cam_periph_mtx(periph), 0);
mtx_lock(&changerq_mtx);
num_changers++;
@@ -1053,7 +1053,7 @@ cdregister(struct cam_periph *periph, vo
/*
* Schedule a periodic media polling events.
*/
- callout_init_mtx(&softc->mediapoll_c, periph->sim->mtx, 0);
+ callout_init_mtx(&softc->mediapoll_c, cam_periph_mtx(periph), 0);
if ((softc->flags & CD_FLAG_DISC_REMOVABLE) &&
(softc->flags & CD_FLAG_CHANGER) == 0 &&
(cgd->inq_flags & SID_AEN) == 0 &&
Modified: projects/camlock/sys/cam/scsi/scsi_ch.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_ch.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/scsi/scsi_ch.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -247,20 +247,19 @@ chinit(void)
static void
chdevgonecb(void *arg)
{
- struct cam_sim *sim;
struct ch_softc *softc;
struct cam_periph *periph;
+ struct mtx *mtx;
int i;
periph = (struct cam_periph *)arg;
- sim = periph->sim;
- softc = (struct ch_softc *)periph->softc;
+ mtx = cam_periph_mtx(periph);
+ mtx_lock(mtx);
+ softc = (struct ch_softc *)periph->softc;
KASSERT(softc->open_count >= 0, ("Negative open count %d",
softc->open_count));
- mtx_lock(sim->mtx);
-
/*
* When we get this callback, we will get no more close calls from
* devfs. So if we have any dangling opens, we need to release the
@@ -277,13 +276,13 @@ chdevgonecb(void *arg)
cam_periph_release_locked(periph);
/*
- * We reference the SIM lock directly here, instead of using
+ * We reference the lock directly here, instead of using
* cam_periph_unlock(). The reason is that the final call to
* cam_periph_release_locked() above could result in the periph
* getting freed. If that is the case, dereferencing the periph
* with a cam_periph_unlock() call would cause a page fault.
*/
- mtx_unlock(sim->mtx);
+ mtx_unlock(mtx);
}
static void
@@ -507,25 +506,23 @@ chopen(struct cdev *dev, int flags, int
static int
chclose(struct cdev *dev, int flag, int fmt, struct thread *td)
{
- struct cam_sim *sim;
struct cam_periph *periph;
struct ch_softc *softc;
+ struct mtx *mtx;
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL)
return(ENXIO);
+ mtx = cam_periph_mtx(periph);
+ mtx_lock(mtx);
- sim = periph->sim;
softc = (struct ch_softc *)periph->softc;
-
- mtx_lock(sim->mtx);
-
softc->open_count--;
cam_periph_release_locked(periph);
/*
- * We reference the SIM lock directly here, instead of using
+ * We reference the lock directly here, instead of using
* cam_periph_unlock(). The reason is that the call to
* cam_periph_release_locked() above could result in the periph
* getting freed. If that is the case, dereferencing the periph
@@ -536,7 +533,7 @@ chclose(struct cdev *dev, int flag, int
* protect the open count and avoid another lock acquisition and
* release.
*/
- mtx_unlock(sim->mtx);
+ mtx_unlock(mtx);
return(0);
}
@@ -1715,10 +1712,8 @@ chscsiversion(struct cam_periph *periph)
struct scsi_inquiry_data *inq_data;
struct ccb_getdev *cgd;
int dev_scsi_version;
- struct cam_sim *sim;
- sim = xpt_path_sim(periph->path);
- mtx_assert(sim->mtx, MA_OWNED);
+ cam_periph_assert(periph, MA_OWNED);
if ((cgd = (struct ccb_getdev *)xpt_alloc_ccb_nowait()) == NULL)
return (-1);
/*
Modified: projects/camlock/sys/cam/scsi/scsi_da.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_da.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/scsi/scsi_da.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -2037,7 +2037,7 @@ daregister(struct cam_periph *periph, vo
* Schedule a periodic event to occasionally send an
* ordered tag to a device.
*/
- callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0);
+ callout_init_mtx(&softc->sendordered_c, cam_periph_mtx(periph), 0);
callout_reset(&softc->sendordered_c,
(da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL,
dasendorderedtag, softc);
@@ -2157,7 +2157,7 @@ daregister(struct cam_periph *periph, vo
/*
* Schedule a periodic media polling events.
*/
- callout_init_mtx(&softc->mediapoll_c, periph->sim->mtx, 0);
+ callout_init_mtx(&softc->mediapoll_c, cam_periph_mtx(periph), 0);
if ((softc->flags & DA_FLAG_PACK_REMOVABLE) &&
(cgd->inq_flags & SID_AEN) == 0 &&
da_poll_period != 0)
Modified: projects/camlock/sys/cam/scsi/scsi_enc.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_enc.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/scsi/scsi_enc.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -110,17 +110,16 @@ enc_init(void)
static void
enc_devgonecb(void *arg)
{
- struct cam_sim *sim;
struct cam_periph *periph;
struct enc_softc *enc;
+ struct mtx *mtx;
int i;
periph = (struct cam_periph *)arg;
- sim = periph->sim;
+ mtx = cam_periph_mtx(periph);
+ mtx_lock(mtx);
enc = (struct enc_softc *)periph->softc;
- mtx_lock(sim->mtx);
-
/*
* When we get this callback, we will get no more close calls from
* devfs. So if we have any dangling opens, we need to release the
@@ -137,13 +136,13 @@ enc_devgonecb(void *arg)
cam_periph_release_locked(periph);
/*
- * We reference the SIM lock directly here, instead of using
+ * We reference the lock directly here, instead of using
* cam_periph_unlock(). The reason is that the final call to
* cam_periph_release_locked() above could result in the periph
* getting freed. If that is the case, dereferencing the periph
* with a cam_periph_unlock() call would cause a page fault.
*/
- mtx_unlock(sim->mtx);
+ mtx_unlock(mtx);
}
static void
@@ -301,25 +300,23 @@ out:
static int
enc_close(struct cdev *dev, int flag, int fmt, struct thread *td)
{
- struct cam_sim *sim;
struct cam_periph *periph;
struct enc_softc *enc;
+ struct mtx *mtx;
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL)
return (ENXIO);
+ mtx = cam_periph_mtx(periph);
+ mtx_lock(mtx);
- sim = periph->sim;
enc = periph->softc;
-
- mtx_lock(sim->mtx);
-
enc->open_count--;
cam_periph_release_locked(periph);
/*
- * We reference the SIM lock directly here, instead of using
+ * We reference the lock directly here, instead of using
* cam_periph_unlock(). The reason is that the call to
* cam_periph_release_locked() above could result in the periph
* getting freed. If that is the case, dereferencing the periph
@@ -330,7 +327,7 @@ enc_close(struct cdev *dev, int flag, in
* protect the open count and avoid another lock acquisition and
* release.
*/
- mtx_unlock(sim->mtx);
+ mtx_unlock(mtx);
return (0);
}
@@ -865,7 +862,7 @@ enc_kproc_init(enc_softc_t *enc)
{
int result;
- callout_init_mtx(&enc->status_updater, enc->periph->sim->mtx, 0);
+ callout_init_mtx(&enc->status_updater, cam_periph_mtx(enc->periph), 0);
if (cam_periph_acquire(enc->periph) != CAM_REQ_CMP)
return (ENXIO);
Modified: projects/camlock/sys/cam/scsi/scsi_enc_ses.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_enc_ses.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/scsi/scsi_enc_ses.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -915,10 +915,8 @@ ses_path_iter_devid_callback(enc_softc_t
cdm.matches = &match_result;
sim = xpt_path_sim(cdm.ccb_h.path);
- CAM_SIM_LOCK(sim);
xpt_action((union ccb *)&cdm);
xpt_free_path(cdm.ccb_h.path);
- CAM_SIM_UNLOCK(sim);
if ((cdm.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP
|| (cdm.status != CAM_DEV_MATCH_LAST
@@ -935,10 +933,7 @@ ses_path_iter_devid_callback(enc_softc_t
args->callback(enc, elem, cdm.ccb_h.path, args->callback_arg);
- sim = xpt_path_sim(cdm.ccb_h.path);
- CAM_SIM_LOCK(sim);
xpt_free_path(cdm.ccb_h.path);
- CAM_SIM_UNLOCK(sim);
}
/**
Modified: projects/camlock/sys/cam/scsi/scsi_pass.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_pass.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/scsi/scsi_pass.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -139,20 +139,19 @@ passinit(void)
static void
passdevgonecb(void *arg)
{
- struct cam_sim *sim;
struct cam_periph *periph;
+ struct mtx *mtx;
struct pass_softc *softc;
int i;
periph = (struct cam_periph *)arg;
- sim = periph->sim;
- softc = (struct pass_softc *)periph->softc;
+ mtx = cam_periph_mtx(periph);
+ mtx_lock(mtx);
+ softc = (struct pass_softc *)periph->softc;
KASSERT(softc->open_count >= 0, ("Negative open count %d",
softc->open_count));
- mtx_lock(sim->mtx);
-
/*
* When we get this callback, we will get no more close calls from
* devfs. So if we have any dangling opens, we need to release the
@@ -169,13 +168,13 @@ passdevgonecb(void *arg)
cam_periph_release_locked(periph);
/*
- * We reference the SIM lock directly here, instead of using
+ * We reference the lock directly here, instead of using
* cam_periph_unlock(). The reason is that the final call to
* cam_periph_release_locked() above could result in the periph
* getting freed. If that is the case, dereferencing the periph
* with a cam_periph_unlock() call would cause a page fault.
*/
- mtx_unlock(sim->mtx);
+ mtx_unlock(mtx);
}
static void
@@ -501,25 +500,23 @@ passopen(struct cdev *dev, int flags, in
static int
passclose(struct cdev *dev, int flag, int fmt, struct thread *td)
{
- struct cam_sim *sim;
struct cam_periph *periph;
struct pass_softc *softc;
+ struct mtx *mtx;
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL)
return (ENXIO);
+ mtx = cam_periph_mtx(periph);
+ mtx_lock(mtx);
- sim = periph->sim;
softc = periph->softc;
-
- mtx_lock(sim->mtx);
-
softc->open_count--;
cam_periph_release_locked(periph);
/*
- * We reference the SIM lock directly here, instead of using
+ * We reference the lock directly here, instead of using
* cam_periph_unlock(). The reason is that the call to
* cam_periph_release_locked() above could result in the periph
* getting freed. If that is the case, dereferencing the periph
@@ -530,7 +527,7 @@ passclose(struct cdev *dev, int flag, in
* protect the open count and avoid another lock acquisition and
* release.
*/
- mtx_unlock(sim->mtx);
+ mtx_unlock(mtx);
return (0);
}
Modified: projects/camlock/sys/cam/scsi/scsi_sg.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_sg.c Sun Aug 11 10:35:38 2013 (r254213)
+++ projects/camlock/sys/cam/scsi/scsi_sg.c Sun Aug 11 10:54:16 2013 (r254214)
@@ -170,20 +170,19 @@ sginit(void)
static void
sgdevgonecb(void *arg)
{
- struct cam_sim *sim;
struct cam_periph *periph;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list