Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Mar 2007 22:12:09 GMT
From:      Scott Long <scottl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 116506 for review
Message-ID:  <200703242212.l2OMC9AL034519@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=116506

Change 116506 by scottl@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);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703242212.l2OMC9AL034519>