svn commit: r315831 - stable/10/sys/dev/firewire
Andriy Gapon
avg at FreeBSD.org
Thu Mar 23 07:56:15 UTC 2017
Author: avg
Date: Thu Mar 23 07:56:13 2017
New Revision: 315831
URL: https://svnweb.freebsd.org/changeset/base/315831
Log:
MFC r314864: firewire/sbp: try to improve locking, plus a few style nits
Modified:
stable/10/sys/dev/firewire/sbp.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/firewire/sbp.c
==============================================================================
--- stable/10/sys/dev/firewire/sbp.c Thu Mar 23 07:56:07 2017 (r315830)
+++ stable/10/sys/dev/firewire/sbp.c Thu Mar 23 07:56:13 2017 (r315831)
@@ -455,7 +455,6 @@ sbp_alloc_lun(struct sbp_target *target)
int maxlun, lun, i;
sbp = target->sbp;
- SBP_LOCK_ASSERT(sbp);
crom_init_context(&cc, target->fwdev->csrrom);
/* XXX shoud parse appropriate unit directories only */
maxlun = -1;
@@ -588,7 +587,9 @@ END_DEBUG
goto next;
}
callout_init_mtx(&ocb->timer, &sbp->mtx, 0);
+ SBP_LOCK(sbp);
sbp_free_ocb(sdev, ocb);
+ SBP_UNLOCK(sbp);
}
next:
crom_next(&cc);
@@ -718,9 +719,8 @@ END_DEBUG
&& crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2))
static void
-sbp_probe_target(void *arg)
+sbp_probe_target(struct sbp_target *target)
{
- struct sbp_target *target = (struct sbp_target *)arg;
struct sbp_softc *sbp = target->sbp;
struct sbp_dev *sdev;
int i, alive;
@@ -732,8 +732,6 @@ SBP_DEBUG(1)
(!alive) ? " not " : "");
END_DEBUG
- sbp = target->sbp;
- SBP_LOCK_ASSERT(sbp);
sbp_alloc_lun(target);
/* XXX untimeout mgm_ocb and dequeue */
@@ -749,7 +747,9 @@ END_DEBUG
sbp_probe_lun(sdev);
sbp_show_sdev_info(sdev);
+ SBP_LOCK(sbp);
sbp_abort_all_ocbs(sdev, CAM_SCSI_BUS_RESET);
+ SBP_UNLOCK(sbp);
switch (sdev->status) {
case SBP_DEV_RESET:
/* new or revived target */
@@ -804,9 +804,9 @@ SBP_DEBUG(0)
printf("sbp_post_busreset\n");
END_DEBUG
SBP_LOCK(sbp);
- if ((sbp->sim->flags & SIMQ_FREEZED) == 0) {
+ if ((sbp->flags & SIMQ_FREEZED) == 0) {
xpt_freeze_simq(sbp->sim, /*count*/1);
- sbp->sim->flags |= SIMQ_FREEZED;
+ sbp->flags |= SIMQ_FREEZED;
}
microtime(&sbp->last_busreset);
SBP_UNLOCK(sbp);
@@ -831,19 +831,15 @@ END_DEBUG
sbp_cold --;
SBP_LOCK(sbp);
-#if 0
- /*
- * XXX don't let CAM the bus rest.
- * CAM tries to do something with freezed (DEV_RETRY) devices.
- */
- xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
-#endif
/* Garbage Collection */
for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
target = &sbp->targets[i];
+ if (target->fwdev == NULL)
+ continue;
+
STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link)
- if (target->fwdev == NULL || target->fwdev == fwdev)
+ if (target->fwdev == fwdev)
break;
if (fwdev == NULL) {
/* device has removed in lower driver */
@@ -851,6 +847,7 @@ END_DEBUG
sbp_free_target(target);
}
}
+
/* traverse device list */
STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link) {
SBP_DEBUG(0)
@@ -877,12 +874,24 @@ END_DEBUG
continue;
}
}
- sbp_probe_target((void *)target);
+
+ /*
+ * It is safe to drop the lock here as the target is already
+ * reserved, so there should be no contenders for it.
+ * And the target is not yet exposed, so there should not be
+ * any other accesses to it.
+ * Finally, the list being iterated is protected somewhere else.
+ */
+ SBP_UNLOCK(sbp);
+ sbp_probe_target(target);
+ SBP_LOCK(sbp);
if (target->num_lun == 0)
sbp_free_target(target);
}
- xpt_release_simq(sbp->sim, /*run queue*/TRUE);
- sbp->sim->flags &= ~SIMQ_FREEZED;
+ if ((sbp->flags & SIMQ_FREEZED) != 0) {
+ xpt_release_simq(sbp->sim, /*run queue*/TRUE);
+ sbp->flags &= ~SIMQ_FREEZED;
+ }
SBP_UNLOCK(sbp);
}
@@ -989,30 +998,36 @@ sbp_next_dev(struct sbp_target *target,
static void
sbp_cam_scan_lun(struct cam_periph *periph, union ccb *ccb)
{
+ struct sbp_softc *sbp;
struct sbp_target *target;
struct sbp_dev *sdev;
sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr;
target = sdev->target;
- SBP_LOCK_ASSERT(target->sbp);
+ sbp = target->sbp;
+ SBP_LOCK(sbp);
SBP_DEBUG(0)
- device_printf(sdev->target->sbp->fd.dev,
+ device_printf(sbp->fd.dev,
"%s:%s\n", __func__, sdev->bustgtlun);
END_DEBUG
if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
sdev->status = SBP_DEV_ATTACHED;
} else {
- device_printf(sdev->target->sbp->fd.dev,
+ device_printf(sbp->fd.dev,
"%s:%s failed\n", __func__, sdev->bustgtlun);
}
sdev = sbp_next_dev(target, sdev->lun_id + 1);
if (sdev == NULL) {
+ SBP_UNLOCK(sbp);
free(ccb, M_SBP);
return;
}
/* reuse ccb */
xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
ccb->ccb_h.ccb_sdev_ptr = sdev;
+ ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
+ SBP_UNLOCK(sbp);
+
xpt_action(ccb);
xpt_release_devq(sdev->path, sdev->freeze, TRUE);
sdev->freeze = 1;
@@ -1041,6 +1056,8 @@ END_DEBUG
printf("sbp_cam_scan_target: malloc failed\n");
return;
}
+ SBP_UNLOCK(target->sbp);
+
xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
ccb->ccb_h.func_code = XPT_SCAN_LUN;
ccb->ccb_h.cbfcnp = sbp_cam_scan_lun;
@@ -1050,6 +1067,8 @@ END_DEBUG
/* The scan is in progress now. */
xpt_action(ccb);
+
+ SBP_LOCK(target->sbp);
xpt_release_devq(sdev->path, sdev->freeze, TRUE);
sdev->freeze = 1;
}
@@ -2015,8 +2034,8 @@ END_DEBUG
sbp->fd.post_explore = sbp_post_explore;
if (fc->status != -1) {
- sbp_post_busreset((void *)sbp);
- sbp_post_explore((void *)sbp);
+ sbp_post_busreset(sbp);
+ sbp_post_explore(sbp);
}
SBP_LOCK(sbp);
xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
More information about the svn-src-stable
mailing list