summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2003-09-04 16:30:03 +0000
committernjl <njl@FreeBSD.org>2003-09-04 16:30:03 +0000
commit657b53c623f5bca13deb8635bd9576243958912c (patch)
tree52cdc3ddbfa474aa07bc6192384e79b64a7424f3 /sys/cam
parentc54c55a75cfcc2fdea6cd7efcc88e89cae29f87b (diff)
downloadFreeBSD-src-657b53c623f5bca13deb8635bd9576243958912c.zip
FreeBSD-src-657b53c623f5bca13deb8635bd9576243958912c.tar.gz
Calling KNOTE with locks held may result in recursion when it calls back
into targreadfilt(). Unlock around calls to notify_user(). If an application is sending CCBs while the endpoint is shutting down, this may result in incomplete disable. A more complete solution will come with a "dying" flag. Submitted by: simokawa
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/scsi/scsi_target.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c
index 4f9187a..ec8894d 100644
--- a/sys/cam/scsi/scsi_target.c
+++ b/sys/cam/scsi/scsi_target.c
@@ -823,6 +823,7 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
case XPT_CONT_TARGET_IO:
TAILQ_INSERT_TAIL(&softc->user_ccb_queue, &done_ccb->ccb_h,
periph_links.tqe);
+ TARG_UNLOCK(softc);
notify_user(softc);
break;
default:
@@ -830,7 +831,6 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
done_ccb->ccb_h.func_code);
/* NOTREACHED */
}
- TARG_UNLOCK(softc);
}
/* Return CCBs to the user from the user queue and abort queue */
@@ -1096,8 +1096,19 @@ abort_all_pending(struct targ_softc *softc)
/* If we aborted anything from the work queue, wakeup user. */
if (!TAILQ_EMPTY(&softc->user_ccb_queue)
- || !TAILQ_EMPTY(&softc->abort_queue))
+ || !TAILQ_EMPTY(&softc->abort_queue)) {
+ /*
+ * XXX KNOTE calls back into targreadfilt, causing a
+ * lock recursion. So unlock around calls to it although
+ * this may open up a race allowing a user to submit
+ * another CCB after we have aborted all pending ones
+ * A better approach is to mark the softc as dying
+ * under lock and check for this in targstart().
+ */
+ TARG_UNLOCK(softc);
notify_user(softc);
+ TARG_LOCK(softc);
+ }
}
/* Notify the user that data is ready */
OpenPOWER on IntegriCloud