PERFORCE change 116506 for review
Scott Long
scottl at FreeBSD.org
Sat Mar 24 22:12:10 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=116506
Change 116506 by scottl at scottl-x64 on 2007/03/24 22:11:21
Remove spls. Move from a global timeout handler for ordered tags to
a per-periph callout.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_da.c#25 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_da.c#25 (text+ko) ====
@@ -136,6 +136,7 @@
struct task sysctl_task;
struct sysctl_ctx_list sysctl_ctx;
struct sysctl_oid *sysctl_tree;
+ struct callout sendordered_c;
};
struct da_quirk_entry {
@@ -554,8 +555,6 @@
PERIPHDRIVER_DECLARE(da, dadriver);
-static SLIST_HEAD(,da_softc) softc_list;
-
static int
daopen(struct disk *dp)
{
@@ -563,12 +562,9 @@
struct da_softc *softc;
int unit;
int error;
- int s;
- s = splsoftcam();
periph = (struct cam_periph *)dp->d_drv1;
if (periph == NULL) {
- splx(s);
return (ENXIO);
}
@@ -590,7 +586,6 @@
/* Invalidate our pack information. */
softc->flags &= ~DA_FLAG_PACK_INVALID;
}
- splx(s);
error = dagetcapacity(periph);
@@ -707,7 +702,6 @@
{
struct cam_periph *periph;
struct da_softc *softc;
- int s;
periph = (struct cam_periph *)bp->bio_disk->d_drv1;
if (periph == NULL) {
@@ -730,13 +724,11 @@
* after we are in the queue. Otherwise, we might not properly
* clean up one of the buffers.
*/
- s = splbio();
/*
* If the device has been made invalid, error out
*/
if ((softc->flags & DA_FLAG_PACK_INVALID)) {
- splx(s);
cam_periph_unlock(periph);
biofinish(bp, NULL, ENXIO);
return;
@@ -747,8 +739,6 @@
*/
bioq_disksort(&softc->bio_queue, bp);
- splx(s);
-
/*
* Schedule ourselves for performing the work.
*/
@@ -857,8 +847,6 @@
cam_status status;
struct cam_path *path;
- SLIST_INIT(&softc_list);
-
/*
* Install a global async callback. This callback will
* receive async callbacks like "new device found".
@@ -884,13 +872,6 @@
"due to status 0x%x!\n", status);
} else if (da_send_ordered) {
- /*
- * Schedule a periodic event to occasionally send an
- * ordered tag to a device.
- */
- timeout(dasendorderedtag, NULL,
- (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL);
-
/* Register our shutdown event handler */
if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown,
NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
@@ -901,7 +882,6 @@
static void
daoninvalidate(struct cam_periph *periph)
{
- int s;
struct da_softc *softc;
struct ccb_setasync csa;
@@ -921,21 +901,11 @@
softc->flags |= DA_FLAG_PACK_INVALID;
/*
- * Although the oninvalidate() routines are always called at
- * splsoftcam, we need to be at splbio() here to keep the buffer
- * queue from being modified while we traverse it.
- */
- s = splbio();
-
- /*
* Return all queued I/O with ENXIO.
* XXX Handle any transactions queued to the card
* with XPT_ABORT_CCB.
*/
bioq_flush(&softc->bio_queue, NULL, ENXIO);
- splx(s);
-
- SLIST_REMOVE(&softc_list, softc, da_softc, links);
disk_gone(softc->disk);
xpt_print(periph->path, "lost device\n");
@@ -957,6 +927,14 @@
xpt_print(periph->path, "can't remove sysctl context\n");
}
disk_destroy(softc->disk);
+
+ /*
+ * XXX Gotta drop the periph lock so that the drain can complete with
+ * deadlocking on the lock. Hopefully dropping here is safe.
+ */
+ cam_periph_unlock(periph);
+ callout_drain(&softc->sendordered_c);
+ cam_periph_lock(periph);
free(softc, M_DEVBUF);
}
@@ -1006,10 +984,8 @@
{
struct da_softc *softc;
struct ccb_hdr *ccbh;
- int s;
softc = (struct da_softc *)periph->softc;
- s = splsoftcam();
/*
* Don't fail on the expected unit attention
* that will occur.
@@ -1017,7 +993,6 @@
softc->flags |= DA_FLAG_RETRY_UA;
LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
ccbh->ccb_state |= DA_CCB_RETRY_UA;
- splx(s);
/* FALLTHROUGH*/
}
default:
@@ -1098,7 +1073,6 @@
static cam_status
daregister(struct cam_periph *periph, void *arg)
{
- int s;
struct da_softc *softc;
struct ccb_setasync csa;
struct ccb_pathinq cpi;
@@ -1188,14 +1162,6 @@
softc->minimum_cmd_size = 16;
/*
- * Block our timeout handler while we
- * add this softc to the dev list.
- */
- s = splsoftclock();
- SLIST_INSERT_HEAD(&softc_list, softc, links);
- splx(s);
-
- /*
* Register this media as a disk
*/
@@ -1229,10 +1195,23 @@
csa.callback = daasync;
csa.callback_arg = periph;
xpt_action((union ccb *)&csa);
- /* Refcount this periph now that it's been created. */
+
+ /*
+ * Refcount the periph while dastart is called to finish the probe.
+ * The reference will be dropped in dadone at the end of probe.
+ */
(void)cam_periph_acquire(periph);
xpt_schedule(periph, /*priority*/5);
+ /*
+ * Schedule a periodic event to occasionally send an
+ * ordered tag to a device.
+ */
+ callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0);
+ callout_reset(&softc->sendordered_c,
+ (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL,
+ dasendorderedtag, softc);
+
return(CAM_REQ_CMP);
}
@@ -1249,12 +1228,10 @@
{
/* Pull a buffer from the queue and get going on it */
struct bio *bp;
- int s;
/*
* See if there is a buf with work for us to do..
*/
- s = splbio();
bp = bioq_first(&softc->bio_queue);
if (periph->immediate_priority <= periph->pinfo.priority) {
CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
@@ -1263,13 +1240,10 @@
SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
periph_links.sle);
periph->immediate_priority = CAM_PRIORITY_NONE;
- splx(s);
wakeup(&periph->ccb_list);
} else if (bp == NULL) {
- splx(s);
xpt_release_ccb(start_ccb);
} else {
- int oldspl;
u_int8_t tag_code;
bioq_remove(&softc->bio_queue, bp);
@@ -1316,11 +1290,9 @@
* Block out any asyncronous callbacks
* while we touch the pending ccb list.
*/
- oldspl = splcam();
LIST_INSERT_HEAD(&softc->pending_ccbs,
&start_ccb->ccb_h, periph_links.le);
softc->outstanding_cmds++;
- splx(oldspl);
/* We expect a unit attention from this device */
if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
@@ -1330,7 +1302,6 @@
start_ccb->ccb_h.ccb_bp = bp;
bp = bioq_first(&softc->bio_queue);
- splx(s);
xpt_action(start_ccb);
}
@@ -1455,12 +1426,10 @@
case DA_CCB_BUFFER_IO:
{
struct bio *bp;
- int oldspl;
bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
int error;
- int s;
int sf;
if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0)
@@ -1478,8 +1447,6 @@
}
if (error != 0) {
- s = splbio();
-
if (error == ENXIO) {
/*
* Catastrophic error. Mark our pack as
@@ -1500,7 +1467,6 @@
* proper order should it attempt to recover.
*/
bioq_flush(&softc->bio_queue, NULL, EIO);
- splx(s);
bp->bio_error = error;
bp->bio_resid = bp->bio_bcount;
bp->bio_flags |= BIO_ERROR;
@@ -1528,12 +1494,10 @@
* Block out any asyncronous callbacks
* while we touch the pending ccb list.
*/
- oldspl = splcam();
LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
softc->outstanding_cmds--;
if (softc->outstanding_cmds == 0)
softc->flags |= DA_FLAG_WENT_IDLE;
- splx(oldspl);
biodone(bp);
break;
@@ -1966,27 +1930,22 @@
static void
dasendorderedtag(void *arg)
{
- struct da_softc *softc;
- int s;
+ struct da_softc *softc = arg;
+
if (da_send_ordered) {
- for (softc = SLIST_FIRST(&softc_list);
- softc != NULL;
- softc = SLIST_NEXT(softc, links)) {
- s = splsoftcam();
- if ((softc->ordered_tag_count == 0)
- && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
- softc->flags |= DA_FLAG_NEED_OTAG;
- }
- if (softc->outstanding_cmds > 0)
- softc->flags &= ~DA_FLAG_WENT_IDLE;
+ if ((softc->ordered_tag_count == 0)
+ && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
+ softc->flags |= DA_FLAG_NEED_OTAG;
+ }
+ if (softc->outstanding_cmds > 0)
+ softc->flags &= ~DA_FLAG_WENT_IDLE;
- softc->ordered_tag_count = 0;
- splx(s);
- }
- /* Queue us up again */
- timeout(dasendorderedtag, NULL,
- (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL);
+ softc->ordered_tag_count = 0;
}
+ /* Queue us up again */
+ callout_reset(&softc->sendordered_c,
+ (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL,
+ dasendorderedtag, softc);
}
/*
More information about the p4-projects
mailing list