svn commit: r255150 - projects/camlock/sys/cam
Alexander Motin
mav at FreeBSD.org
Mon Sep 2 16:20:11 UTC 2013
Author: mav
Date: Mon Sep 2 16:20:10 2013
New Revision: 255150
URL: http://svnweb.freebsd.org/changeset/base/255150
Log:
- Add missing locking around cam_ccbq_resize() call.
- Reshuffle xpt_done_process() to reduce device lock scope.
Modified:
projects/camlock/sys/cam/cam_xpt.c
Modified: projects/camlock/sys/cam/cam_xpt.c
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.c Mon Sep 2 15:52:48 2013 (r255149)
+++ projects/camlock/sys/cam/cam_xpt.c Mon Sep 2 16:20:10 2013 (r255150)
@@ -4809,7 +4809,9 @@ xpt_dev_ccbq_resize(struct cam_path *pat
struct cam_ed *dev;
dev = path->device;
+ mtx_lock(&dev->sim->devq->send_mtx);
result = cam_ccbq_resize(&dev->ccbq, newopenings);
+ mtx_unlock(&dev->sim->devq->send_mtx);
if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
|| (dev->inq_flags & SID_CmdQue) != 0)
dev->tag_saved_openings = newopenings;
@@ -5158,7 +5160,8 @@ static void
xpt_done_process(struct ccb_hdr *ccb_h)
{
struct cam_sim *sim;
- struct mtx *mtx;
+ struct cam_devq *devq;
+ struct mtx *mtx = NULL;
if (ccb_h->flags & CAM_HIGH_POWER) {
struct highpowerlist *hphead;
@@ -5191,15 +5194,26 @@ xpt_done_process(struct ccb_hdr *ccb_h)
}
sim = ccb_h->path->bus->sim;
- mtx = xpt_path_mtx(ccb_h->path);
- mtx_lock(mtx);
+ if (ccb_h->status & CAM_RELEASE_SIMQ) {
+ xpt_release_simq(sim, /*run_queue*/FALSE);
+ ccb_h->status &= ~CAM_RELEASE_SIMQ;
+ }
+
+ if ((ccb_h->flags & CAM_DEV_QFRZDIS)
+ && (ccb_h->status & CAM_DEV_QFRZN)) {
+ xpt_release_devq(ccb_h->path, /*count*/1,
+ /*run_queue*/FALSE);
+ ccb_h->status &= ~CAM_DEV_QFRZN;
+ }
+
+ devq = sim->devq;
if ((ccb_h->func_code & XPT_FC_USER_CCB) == 0) {
struct cam_ed *dev;
- mtx_lock(&sim->devq->send_mtx);
- sim->devq->send_active--;
- sim->devq->send_openings++;
+ mtx_lock(&devq->send_mtx);
+ devq->send_active--;
+ devq->send_openings++;
dev = ccb_h->path->device;
cam_ccbq_ccb_done(&dev->ccbq, (union ccb *)ccb_h);
@@ -5219,29 +5233,23 @@ xpt_done_process(struct ccb_hdr *ccb_h)
}
if (!device_is_queued(dev))
- (void)xpt_schedule_devq(sim->devq, dev);
- mtx_unlock(&sim->devq->send_mtx);
+ (void)xpt_schedule_devq(devq, dev);
+ mtx_unlock(&devq->send_mtx);
+
+ mtx = xpt_path_mtx(ccb_h->path);
+ mtx_lock(mtx);
if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
&& (--dev->tag_delay_count == 0))
xpt_start_tags(ccb_h->path);
- }
- if (ccb_h->status & CAM_RELEASE_SIMQ) {
- xpt_release_simq(sim, /*run_queue*/FALSE);
- ccb_h->status &= ~CAM_RELEASE_SIMQ;
- }
-
- if ((ccb_h->flags & CAM_DEV_QFRZDIS)
- && (ccb_h->status & CAM_DEV_QFRZN)) {
- xpt_release_devq(ccb_h->path, /*count*/1,
- /*run_queue*/FALSE);
- ccb_h->status &= ~CAM_DEV_QFRZN;
- }
-
- if (ccb_h->flags & CAM_UNLOCKED) {
- mtx_unlock(mtx);
- mtx = NULL;
+ if ((ccb_h->flags & CAM_UNLOCKED) != 0) {
+ mtx_unlock(mtx);
+ mtx = NULL;
+ }
+ } else if ((ccb_h->flags & CAM_UNLOCKED) == 0) {
+ mtx = xpt_path_mtx(ccb_h->path);
+ mtx_lock(mtx);
}
/* Call the peripheral driver's callback */
@@ -5249,9 +5257,9 @@ xpt_done_process(struct ccb_hdr *ccb_h)
if (mtx != NULL)
mtx_unlock(mtx);
- mtx_lock(&sim->devq->send_mtx);
- xpt_run_devq(sim->devq);
- mtx_unlock(&sim->devq->send_mtx);
+ mtx_lock(&devq->send_mtx);
+ xpt_run_devq(devq);
+ mtx_unlock(&devq->send_mtx);
}
void
More information about the svn-src-projects
mailing list