summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authorjmg <jmg@FreeBSD.org>2004-08-15 06:24:42 +0000
committerjmg <jmg@FreeBSD.org>2004-08-15 06:24:42 +0000
commitbc1805c6e871c178d0b6516c3baa774ffd77224a (patch)
tree1172b68a7c9e7fa73090ae134eb98825bdab8ad6 /sys/cam
parent57da12d01618c3ef2590eab07e71f69d16ead13a (diff)
downloadFreeBSD-src-bc1805c6e871c178d0b6516c3baa774ffd77224a.zip
FreeBSD-src-bc1805c6e871c178d0b6516c3baa774ffd77224a.tar.gz
Add locking to the kqueue subsystem. This also makes the kqueue subsystem
a more complete subsystem, and removes the knowlege of how things are implemented from the drivers. Include locking around filter ops, so a module like aio will know when not to be unloaded if there are outstanding knotes using it's filter ops. Currently, it uses the MTX_DUPOK even though it is not always safe to aquire duplicate locks. Witness currently doesn't support the ability to discover if a dup lock is ok (in some cases). Reviewed by: green, rwatson (both earlier versions)
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/scsi/scsi_target.c26
1 files changed, 5 insertions, 21 deletions
diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c
index 198a70d..a3e3381 100644
--- a/sys/cam/scsi/scsi_target.c
+++ b/sys/cam/scsi/scsi_target.c
@@ -196,6 +196,7 @@ targopen(struct cdev *dev, int flags, int fmt, struct thread *td)
TAILQ_INIT(&softc->work_queue);
TAILQ_INIT(&softc->abort_queue);
TAILQ_INIT(&softc->user_ccb_queue);
+ knlist_init(&softc->read_select.si_note, &softc->mtx);
return (0);
}
@@ -336,9 +337,7 @@ targkqfilter(struct cdev *dev, struct knote *kn)
softc = (struct targ_softc *)dev->si_drv1;
kn->kn_hook = (caddr_t)softc;
kn->kn_fop = &targread_filtops;
- TARG_LOCK(softc);
- SLIST_INSERT_HEAD(&softc->read_select.si_note, kn, kn_selnext);
- TARG_UNLOCK(softc);
+ knlist_add(&softc->read_select.si_note, kn, 0);
return (0);
}
@@ -348,9 +347,7 @@ targreadfiltdetach(struct knote *kn)
struct targ_softc *softc;
softc = (struct targ_softc *)kn->kn_hook;
- TARG_LOCK(softc);
- SLIST_REMOVE(&softc->read_select.si_note, kn, knote, kn_selnext);
- TARG_UNLOCK(softc);
+ knlist_remove(&softc->read_select.si_note, kn, 0);
}
/* Notify the user's kqueue when the user queue or abort queue gets a CCB */
@@ -361,10 +358,8 @@ targreadfilt(struct knote *kn, long hint)
int retval;
softc = (struct targ_softc *)kn->kn_hook;
- TARG_LOCK(softc);
retval = !TAILQ_EMPTY(&softc->user_ccb_queue) ||
!TAILQ_EMPTY(&softc->abort_queue);
- TARG_UNLOCK(softc);
return (retval);
}
@@ -1096,19 +1091,8 @@ 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)) {
- /*
- * 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);
+ || !TAILQ_EMPTY(&softc->abort_queue))
notify_user(softc);
- TARG_LOCK(softc);
- }
}
/* Notify the user that data is ready */
@@ -1120,7 +1104,7 @@ notify_user(struct targ_softc *softc)
* blocking read().
*/
selwakeuppri(&softc->read_select, PRIBIO);
- KNOTE(&softc->read_select.si_note, 0);
+ KNOTE_LOCKED(&softc->read_select.si_note, 0);
wakeup(&softc->user_ccb_queue);
}
OpenPOWER on IntegriCloud