DragonFly kernel List (threaded) for 2008-06
DragonFly BSD
DragonFly kernel List (threaded) for 2008-06
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: Anticipatory disk scheduling - soc 2008


From: "Jeffrey Hsu" <hsu@xxxxxxxxxxx>
Date: Wed, 04 Jun 2008 19:12:14 -0700

  > I am sending this mail , however to find out more
  > details. I could be digging through the code as well but if some of
  > you out there already know what exists it would be great to understand
  > a little more so that i can dig in the right places.

You should break this up into several steps:
  1. existing code cleanup
    a. define new external APIs for the rest of the kernel to use
  2. define internal I/O scheduler API
    a. factor out the existing 1-way elevator scan code
  3. implement anticipatory I/O scheduler

(I suggest you use a source code control tool like Mercurial patch
queue facility to help you manage your code changes.)

I did 1 and 2 a while ago.  This code compiled and worked as of Nov last year.
You're welcome to use this as a base for your project.

							Jeffrey
Index: bus/cam/scsi/scsi_cd.c
===================================================================
RCS file: /a/dcvs/src/sys/bus/cam/scsi/scsi_cd.c,v
retrieving revision 1.33
diff -u -p -r1.33 scsi_cd.c
--- bus/cam/scsi/scsi_cd.c	23 Jul 2007 19:20:43 -0000	1.33
+++ bus/cam/scsi/scsi_cd.c	23 Oct 2007 01:41:22 -0000
@@ -148,7 +148,7 @@ struct cd_softc {
 	cam_pinfo		pinfo;
 	cd_state		state;
 	volatile cd_flags	flags;
-	struct bio_queue_head	bio_queue;
+	bio_queue_head_t	bio_queue;
 	LIST_HEAD(, ccb_hdr)	pending_ccbs;
 	struct cd_params	params;
 	struct disk	 	disk;
@@ -427,8 +427,7 @@ 	 * Return all queued I/O with ENXIO.
 	 * XXX Handle any transactions queued to the card
 	 *     with XPT_ABORT_CCB.
 	 */
-	while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){
-		bioq_remove(&softc->bio_queue, q_bio);
+	while ((q_bio = bioq_remove_first(softc->bio_queue)) != NULL){
 		q_bp = q_bio->bio_buf;
 		q_bp->b_resid = q_bp->b_bcount;
 		q_bp->b_error = ENXIO;
@@ -1119,7 +1118,7 @@ 	/*
 	 * Check to see if there is any more pending or outstanding I/O for
 	 * this device.  If not, move it out of the active slot.
 	 */
-	if ((bioq_first(&changer->cur_device->bio_queue) == NULL)
+	if (bioq_empty(changer->cur_device->bio_queue)
 	 && (changer->cur_device->device_stats.busy_count == 0)) {
 		changer->flags |= CHANGER_MANUAL_CALL;
 		cdrunchangerqueue(changer);
@@ -1242,7 +1241,7 @@ 		 * Check to see whether the current de
 		 * to do.  If so, requeue it at the end of the queue.  If
 		 * not, there is no need to requeue it.
 		 */
-		if (bioq_first(&changer->cur_device->bio_queue) != NULL) {
+		if (!bioq_empty(changer->cur_device->bio_queue)) {
 
 			changer->cur_device->pinfo.generation =
 				++changer->devq.generation;
@@ -1323,7 +1322,7 @@ 					CHANGER_MANUAL_CALL;
 				softc->flags &= ~CD_FLAG_SCHED_ON_COMP;
 				cdrunchangerqueue(softc->changer);
 			}
-		} else if ((bioq_first(&softc->bio_queue) == NULL)
+		} else if (bioq_empty(softc->bio_queue)
 		        && (softc->device_stats.busy_count == 0)) {
 			softc->changer->flags |= CHANGER_MANUAL_CALL;
 			cdrunchangerqueue(softc->changer);
@@ -1485,7 +1484,7 @@ 
 	/*
 	 * Place it in the queue of disk activities for this disk
 	 */
-	bioqdisksort(&softc->bio_queue, bio);
+	bioqdisksort(softc->bio_queue, bio);
 
 	crit_exit();
 	
@@ -1513,7 +1512,7 @@ static void
 cdstart(struct cam_periph *periph, union ccb *start_ccb)
 {
 	struct cd_softc *softc;
-	struct bio *bio;
+	struct bio *bio = NULL;
 	struct buf *bp;
 	struct ccb_scsiio *csio;
 	struct scsi_read_capacity_data *rcap;
@@ -1526,65 +1525,66 @@ 	switch (softc->state) {
 	case CD_STATE_NORMAL:
 	{
 		crit_enter();
-		bio = bioq_first(&softc->bio_queue);
-		if (periph->immediate_priority <= periph->pinfo.priority) {
-			start_ccb->ccb_h.ccb_state = CD_CCB_WAITING;
-
-			SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
-					  periph_links.sle);
-			periph->immediate_priority = CAM_PRIORITY_NONE;
-			crit_exit();
-			wakeup(&periph->ccb_list);
-		} else if (bio == NULL) {
-			crit_exit();
-			xpt_release_ccb(start_ccb);
-		} else {
-			bp = bio->bio_buf;
-			bioq_remove(&softc->bio_queue, bio);
+		if (periph->immediate_priority > periph->pinfo.priority) {
+			bio = bioq_remove_first(softc->bio_queue);
+			if (bio != NULL) {
+				bp = bio->bio_buf;
+				KKASSERT(bio->bio_offset % softc->params.blksize
+					 == 0);
+				devstat_start_transaction(&softc->device_stats);
+
+				scsi_read_write(&start_ccb->csio,
+				    4,			/* retries */
+				    cddone,		/* cbfcnp */
+				    (bp->b_flags & B_ORDERED)?
+					MSG_ORDERED_Q_TAG : MSG_SIMPLE_Q_TAG,
+				    (bp->b_cmd == BUF_CMD_READ), /* read */
+					0,		/* byte2 */
+					10,		/* minimum_cmd_size */
+				    bio->bio_offset / softc->params.blksize,
+				    			/* lba */
+				    bp->b_bcount / softc->params.blksize,
+				    bp->b_data,		/* data_ptr */
+				    bp->b_bcount,	/* dxfer_len */
+				    SSD_FULL_SIZE,	/* sense_len */
+				    30000);		/* timeout */
+				start_ccb->ccb_h.ccb_state = CD_CCB_BUFFER_IO;
 
-			devstat_start_transaction(&softc->device_stats);
-
-			KKASSERT(bio->bio_offset % softc->params.blksize == 0);
+				/*
+				 * Block out any asyncronous callbacks
+				 * while we touch the pending ccb list.
+				 */
+				LIST_INSERT_HEAD(&softc->pending_ccbs,
+						 &start_ccb->ccb_h,
+						 periph_links.le);
 
-			scsi_read_write(&start_ccb->csio,
-					/*retries*/4,
-					/* cbfcnp */ cddone,
-					(bp->b_flags & B_ORDERED) != 0 ?
-					    MSG_ORDERED_Q_TAG : 
-					    MSG_SIMPLE_Q_TAG,
-					/* read */(bp->b_cmd == BUF_CMD_READ),
-					/* byte2 */ 0,
-					/* minimum_cmd_size */ 10,
-					/* lba */ 
-					bio->bio_offset / softc->params.blksize,
-					bp->b_bcount / softc->params.blksize,
-					/* data_ptr */ bp->b_data,
-					/* dxfer_len */ bp->b_bcount,
-					/* sense_len */ SSD_FULL_SIZE,
-					/* timeout */ 30000);
-			start_ccb->ccb_h.ccb_state = CD_CCB_BUFFER_IO;
+				/*
+				 * We expect a unit attention from this device.
+				 */
+				if (softc->flags & CD_FLAG_RETRY_UA) {
+					start_ccb->ccb_h.ccb_state |=
+					    CD_CCB_RETRY_UA;
+					softc->flags &= ~CD_FLAG_RETRY_UA;
+				}
 
-			
-			/*
-			 * Block out any asyncronous callbacks
-			 * while we touch the pending ccb list.
-			 */
-			LIST_INSERT_HEAD(&softc->pending_ccbs,
-					 &start_ccb->ccb_h, periph_links.le);
+				start_ccb->ccb_h.ccb_bio = bio;
+				crit_exit();
 
-			/* We expect a unit attention from this device */
-			if ((softc->flags & CD_FLAG_RETRY_UA) != 0) {
-				start_ccb->ccb_h.ccb_state |= CD_CCB_RETRY_UA;
-				softc->flags &= ~CD_FLAG_RETRY_UA;
+				xpt_action(start_ccb);
+			} else {
+				crit_exit();
+				xpt_release_ccb(start_ccb);
 			}
+		} else {
+			start_ccb->ccb_h.ccb_state = CD_CCB_WAITING;
 
-			start_ccb->ccb_h.ccb_bio = bio;
-			bio = bioq_first(&softc->bio_queue);
+			SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
+					  periph_links.sle);
+			periph->immediate_priority = CAM_PRIORITY_NONE;
 			crit_exit();
-
-			xpt_action(start_ccb);
+			wakeup(&periph->ccb_list);
 		}
-		if (bio != NULL) {
+		if (!bioq_empty(softc->bio_queue)) {
 			/* Have more work to do, so ensure we stay scheduled */
 			xpt_schedule(periph, /* XXX priority */1);
 		}
@@ -1592,7 +1592,6 @@ 		break;
 	}
 	case CD_STATE_PROBE:
 	{
-
 		rcap = kmalloc(sizeof(*rcap), M_TEMP, M_INTWAIT);
 		csio = &start_ccb->csio;
 		scsi_read_capacity(csio,
@@ -1659,8 +1658,8 @@ 
 			xpt_print_path(periph->path);
 			kprintf("cddone: got error %#x back\n", error);
 			crit_enter();
-			while ((q_bio = bioq_first(&softc->bio_queue)) != NULL) {
-				bioq_remove(&softc->bio_queue, q_bio);
+			while ((q_bio = bioq_remove_first(softc->bio_queue))
+			    != NULL) {
 				q_bp = q_bio->bio_buf;
 				q_bp->b_resid = q_bp->b_bcount;
 				q_bp->b_error = EIO;
Index: bus/cam/scsi/scsi_da.c
===================================================================
RCS file: /a/dcvs/src/sys/bus/cam/scsi/scsi_da.c,v
retrieving revision 1.40
diff -u -p -r1.40 scsi_da.c
--- bus/cam/scsi/scsi_da.c	23 Jul 2007 19:20:43 -0000	1.40
+++ bus/cam/scsi/scsi_da.c	11 Oct 2007 04:38:23 -0000
@@ -133,7 +133,7 @@ 	u_int64_t sectors;	/* total number sect
 };
 
 struct da_softc {
-	struct	 bio_queue_head bio_queue;
+	bio_queue_head_t bio_queue;
 	struct	 devstat device_stats;
 	SLIST_ENTRY(da_softc) links;
 	LIST_HEAD(, ccb_hdr) pending_ccbs;
@@ -803,7 +803,7 @@ 	
 	/*
 	 * Place it in the queue of disk activities for this disk
 	 */
-	bioqdisksort(&softc->bio_queue, bio);
+	bioqdisksort(softc->bio_queue, bio);
 
 	crit_exit();
 	
@@ -1071,8 +1071,7 @@ 	 * Return all queued I/O with ENXIO.
 	 * XXX Handle any transactions queued to the card
 	 *     with XPT_ABORT_CCB.
 	 */
-	while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){
-		bioq_remove(&softc->bio_queue, q_bio);
+	while ((q_bio = bioq_remove_first(softc->bio_queue)) != NULL){
 		q_bp = q_bio->bio_buf;
 		q_bp->b_resid = q_bp->b_bcount;
 		q_bp->b_error = ENXIO;
@@ -1379,23 +1378,19 @@ 
 static void
 dastart(struct cam_periph *periph, union ccb *start_ccb)
 {
-	struct da_softc *softc;
-
-	softc = (struct da_softc *)periph->softc;
+	struct da_softc *softc = (struct da_softc *)periph->softc;
 
-	
 	switch (softc->state) {
 	case DA_STATE_NORMAL:
 	{
 		/* Pull a buffer from the queue and get going on it */		
-		struct bio *bio;
+		struct bio *bio = NULL;
 		struct buf *bp;
 
 		/*
 		 * See if there is a buf with work for us to do..
 		 */
 		crit_enter();
-		bio = bioq_first(&softc->bio_queue);
 		if (periph->immediate_priority <= periph->pinfo.priority) {
 			CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
 					("queuing for immediate ccb\n"));
@@ -1405,64 +1400,70 @@ 					  periph_links.sle);
 			periph->immediate_priority = CAM_PRIORITY_NONE;
 			crit_exit();
 			wakeup(&periph->ccb_list);
-		} else if (bio == NULL) {
-			crit_exit();
-			xpt_release_ccb(start_ccb);
 		} else {
-			u_int8_t tag_code;
+			bio = bioq_remove_first(softc->bio_queue);
+			if (bio == NULL) {
+				crit_exit();
+				xpt_release_ccb(start_ccb);
+			} else {
+				u_int8_t tag_code;
 
-			bioq_remove(&softc->bio_queue, bio);
-			bp = bio->bio_buf;
+				bp = bio->bio_buf;
 
-			devstat_start_transaction(&softc->device_stats);
+				devstat_start_transaction(&softc->device_stats);
 
-			if ((bp->b_flags & B_ORDERED) != 0
-			 || (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
-				softc->flags &= ~DA_FLAG_NEED_OTAG;
-				softc->ordered_tag_count++;
-				tag_code = MSG_ORDERED_Q_TAG;
-			} else {
-				tag_code = MSG_SIMPLE_Q_TAG;
-			}
+				if ((bp->b_flags & B_ORDERED) != 0
+				 || (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
+					softc->flags &= ~DA_FLAG_NEED_OTAG;
+					softc->ordered_tag_count++;
+					tag_code = MSG_ORDERED_Q_TAG;
+				} else {
+					tag_code = MSG_SIMPLE_Q_TAG;
+				}
 
-			KKASSERT(bio->bio_offset % softc->params.secsize == 0);
+				KKASSERT(bio->bio_offset %
+					 softc->params.secsize == 0);
 
-			scsi_read_write(&start_ccb->csio,
-					/*retries*/da_retry_count,
-					dadone,
-					tag_code,
-					(bp->b_cmd == BUF_CMD_READ),
-					/*byte2*/0,
-					softc->minimum_cmd_size,
-					bio->bio_offset / softc->params.secsize,
-					bp->b_bcount / softc->params.secsize,
-					bp->b_data,
-					bp->b_bcount,
-					/*sense_len*/SSD_FULL_SIZE,
-					da_default_timeout * 1000);
-			start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
+				scsi_read_write(&start_ccb->csio,
+				    /*retries*/da_retry_count,
+				    dadone,
+				    tag_code,
+				    (bp->b_cmd == BUF_CMD_READ),
+				    /*byte2*/0,
+				    softc->minimum_cmd_size,
+				    bio->bio_offset / softc->params.secsize,
+				    bp->b_bcount / softc->params.secsize,
+				    bp->b_data,
+				    bp->b_bcount,
+				    /*sense_len*/SSD_FULL_SIZE,
+				    da_default_timeout * 1000);
+				start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
 
-			/*
-			 * Block out any asyncronous callbacks
-			 * while we touch the pending ccb list.
-			 */
-			LIST_INSERT_HEAD(&softc->pending_ccbs,
-					 &start_ccb->ccb_h, periph_links.le);
+				/*
+				 * Block out any asyncronous callbacks
+				 * while we touch the pending ccb list.
+				 */
+				LIST_INSERT_HEAD(&softc->pending_ccbs,
+						 &start_ccb->ccb_h,
+						 periph_links.le);
 
-			/* We expect a unit attention from this device */
-			if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
-				start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
-				softc->flags &= ~DA_FLAG_RETRY_UA;
-			}
+				/*
+				 * We expect a unit attention from this device.
+				 */
+				if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
+					start_ccb->ccb_h.ccb_state |=
+					    DA_CCB_RETRY_UA;
+					softc->flags &= ~DA_FLAG_RETRY_UA;
+				}
 
-			start_ccb->ccb_h.ccb_bio = bio;
-			bio = bioq_first(&softc->bio_queue);
-			crit_exit();
+				start_ccb->ccb_h.ccb_bio = bio;
+				crit_exit();
 
-			xpt_action(start_ccb);
+				xpt_action(start_ccb);
+			}
 		}
-		
-		if (bio != NULL) {
+
+		if (!bioq_empty(softc->bio_queue)) {
 			/* Have more work to do, so ensure we stay scheduled */
 			xpt_schedule(periph, /* XXX priority */1);
 		}
@@ -1623,9 +1624,9 @@ 				 * return all queued I/O with EIO, s
 				 * the client can retry these I/Os in the
 				 * proper order should it attempt to recover.
 				 */
-				while ((q_bio = bioq_first(&softc->bio_queue))
-					!= NULL) {
-					bioq_remove(&softc->bio_queue, q_bio);
+				while ((q_bio =
+					bioq_remove_first(softc->bio_queue))
+				    != NULL) {
 					q_bp = q_bio->bio_buf;
 					q_bp->b_resid = q_bp->b_bcount;
 					q_bp->b_error = EIO;
Index: bus/cam/scsi/scsi_pass.c
===================================================================
RCS file: /a/dcvs/src/sys/bus/cam/scsi/scsi_pass.c,v
retrieving revision 1.19
diff -u -p -r1.19 scsi_pass.c
--- bus/cam/scsi/scsi_pass.c	22 Dec 2006 23:12:16 -0000	1.19
+++ bus/cam/scsi/scsi_pass.c	16 Oct 2007 23:05:45 -0000
@@ -79,7 +79,7 @@ struct pass_softc {
 	pass_state	state;
 	pass_flags	flags;
 	u_int8_t	pd_type;
-	struct		bio_queue_head bio_queue;
+	bio_queue_head_t bio_queue;
 	union ccb	saved_ccb;
 	struct devstat	device_stats;
 };
@@ -201,8 +201,7 @@ 	 * Return all queued I/O with ENXIO.
 	 * XXX Handle any transactions queued to the card
 	 *     with XPT_ABORT_CCB.
 	 */
-	while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){
-		bioq_remove(&softc->bio_queue, q_bio);
+	while ((q_bio = bioq_remove_first(softc->bio_queue)) != NULL){
 		q_bp = q_bio->bio_buf;
 		q_bp->b_resid = q_bp->b_bcount;
 		q_bp->b_error = ENXIO;
@@ -486,7 +485,7 @@ 	 * after we are in the queue.  Otherwis
 	 * clean up one of the buffers.
 	 */
 	crit_enter();
-	bioq_insert_tail(&softc->bio_queue, bio);
+	bioq_insert_tail(softc->bio_queue, bio);
 	crit_exit();
 	
 	/*
@@ -516,11 +515,10 @@ 
 	switch (softc->state) {
 	case PASS_STATE_NORMAL:
 	{
-		struct buf *bp;
+		struct buf *bp = NULL;
 		struct bio *bio;
 
 		crit_enter();
-		bio = bioq_first(&softc->bio_queue);
 		if (periph->immediate_priority <= periph->pinfo.priority) {
 			start_ccb->ccb_h.ccb_type = PASS_CCB_WAITING;			
 			SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
@@ -528,35 +526,35 @@ 					  periph_links.sle);
 			periph->immediate_priority = CAM_PRIORITY_NONE;
 			crit_exit();
 			wakeup(&periph->ccb_list);
-		} else if (bio == NULL) {
-			crit_exit();
-			xpt_release_ccb(start_ccb);
 		} else {
+			bio = bioq_remove_first(softc->bio_queue);
+			if (bio == NULL) {
+				crit_exit();
+				xpt_release_ccb(start_ccb);
+			} else {
+				bp = bio->bio_buf;
 
-			bioq_remove(&softc->bio_queue, bio);
-			bp = bio->bio_buf;
+				devstat_start_transaction(&softc->device_stats);
 
-			devstat_start_transaction(&softc->device_stats);
+				/*
+				 * XXX JGibbs -
+				 * Interpret the contents of the bp as a CCB
+				 * and pass it to a routine shared by our ioctl
+				 * code and passtart.
+				 * For now, just biodone it with EIO so we don't
+				 * hang.
+				 */
+				bp->b_error = EIO;
+				bp->b_flags |= B_ERROR;
+				bp->b_resid = bp->b_bcount;
+				biodone(bio);
+				crit_exit();
 
-			/*
-			 * XXX JGibbs -
-			 * Interpret the contents of the bp as a CCB
-			 * and pass it to a routine shared by our ioctl
-			 * code and passtart.
-			 * For now, just biodone it with EIO so we don't
-			 * hang.
-			 */
-			bp->b_error = EIO;
-			bp->b_flags |= B_ERROR;
-			bp->b_resid = bp->b_bcount;
-			biodone(bio);
-			bio = bioq_first(&softc->bio_queue);
-			crit_exit();
-  
-			xpt_action(start_ccb);
+				xpt_action(start_ccb);
 
+			}
 		}
-		if (bio != NULL) {
+		if (!bioq_empty(softc->bio_queue)) {
 			/* Have more work to do, so ensure we stay scheduled */
 			xpt_schedule(periph, /* XXX priority */1);
 		}
Index: bus/cam/scsi/scsi_pt.c
===================================================================
RCS file: /a/dcvs/src/sys/bus/cam/scsi/scsi_pt.c,v
retrieving revision 1.18
diff -u -p -r1.18 scsi_pt.c
--- bus/cam/scsi/scsi_pt.c	22 Dec 2006 23:12:16 -0000	1.18
+++ bus/cam/scsi/scsi_pt.c	11 Oct 2007 04:34:29 -0000
@@ -79,7 +79,7 @@ #define ccb_state	ppriv_field0
 #define ccb_bio		ppriv_ptr1
 
 struct pt_softc {
-	struct	 bio_queue_head bio_queue;
+	bio_queue_head_t bio_queue;
 	struct	 devstat device_stats;
 	LIST_HEAD(, ccb_hdr) pending_ccbs;
 	pt_state state;
@@ -248,7 +248,7 @@ 	
 	/*
 	 * Place it in the queue of disk activities for this disk
 	 */
-	bioq_insert_tail(&softc->bio_queue, bio);
+	bioq_insert_tail(softc->bio_queue, bio);
 
 	crit_exit();
 	
@@ -404,8 +404,7 @@ 	 * Return all queued I/O with ENXIO.
 	 * XXX Handle any transactions queued to the card
 	 *     with XPT_ABORT_CCB.
 	 */
-	while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){
-		bioq_remove(&softc->bio_queue, q_bio);
+	while ((q_bio = bioq_remove_first(softc->bio_queue)) != NULL){
 		q_bp = q_bio->bio_buf;
 		q_bp->b_resid = q_bp->b_bcount;
 		q_bp->b_error = ENXIO;
@@ -506,7 +505,6 @@ 	/*
 	 * See if there is a buf with work for us to do..
 	 */
 	crit_enter();
-	bio = bioq_first(&softc->bio_queue);
 	if (periph->immediate_priority <= periph->pinfo.priority) {
 		CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
 				("queuing for immediate ccb\n"));
@@ -516,46 +514,47 @@ 				  periph_links.sle);
 		periph->immediate_priority = CAM_PRIORITY_NONE;
 		crit_exit();
 		wakeup(&periph->ccb_list);
-	} else if (bio == NULL) {
-		crit_exit();
-		xpt_release_ccb(start_ccb);
 	} else {
-		bioq_remove(&softc->bio_queue, bio);
-		bp = bio->bio_buf;
-
-		devstat_start_transaction(&softc->device_stats);
-
-		scsi_send_receive(&start_ccb->csio,
-				  /*retries*/4,
-				  ptdone,
-				  MSG_SIMPLE_Q_TAG,
-				  (bp->b_cmd == BUF_CMD_READ),
-				  /*byte2*/0,
-				  bp->b_bcount,
-				  bp->b_data,
-				  /*sense_len*/SSD_FULL_SIZE,
-				  /*timeout*/softc->io_timeout);
+		bio = bioq_remove_first(softc->bio_queue);
+		if (bio == NULL) {
+			crit_exit();
+			xpt_release_ccb(start_ccb);
+		} else {
+			bp = bio->bio_buf;
 
-		start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO;
+			devstat_start_transaction(&softc->device_stats);
 
-		/*
-		 * Block out any asyncronous callbacks
-		 * while we touch the pending ccb list.
-		 */
-		LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h,
-				 periph_links.le);
+			scsi_send_receive(&start_ccb->csio,
+					  /*retries*/4,
+					  ptdone,
+					  MSG_SIMPLE_Q_TAG,
+					  (bp->b_cmd == BUF_CMD_READ),
+					  /*byte2*/0,
+					  bp->b_bcount,
+					  bp->b_data,
+					  /*sense_len*/SSD_FULL_SIZE,
+					  /*timeout*/softc->io_timeout);
+
+			start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO;
+
+			/*
+			 * Block out any asyncronous callbacks
+			 * while we touch the pending ccb list.
+			 */
+			LIST_INSERT_HEAD(&softc->pending_ccbs,
+					 &start_ccb->ccb_h, periph_links.le);
 
-		start_ccb->ccb_h.ccb_bio = bio;
-		bio = bioq_first(&softc->bio_queue);
-		crit_exit();
+			start_ccb->ccb_h.ccb_bio = bio;
+			crit_exit();
 
-		xpt_action(start_ccb);
-		
-		if (bio != NULL) {
-			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, /* XXX priority */1);
+			xpt_action(start_ccb);
+			
 		}
 	}
+	if (!bioq_empty(softc->bio_queue)) {
+		/* Have more work to do, so ensure we stay scheduled */
+		xpt_schedule(periph, /* XXX priority */1);
+	}
 }
 
 static void
@@ -615,9 +614,9 @@ 				 * return all queued I/O with EIO, s
 				 * the client can retry these I/Os in the
 				 * proper order should it attempt to recover.
 				 */
-				while ((q_bio = bioq_first(&softc->bio_queue))
-					!= NULL) {
-					bioq_remove(&softc->bio_queue, q_bio);
+				while ((q_bio =
+					bioq_remove_first(softc->bio_queue))
+				    != NULL) {
 					q_bp = q_bio->bio_buf;
 					q_bp->b_resid = q_bp->b_bcount;
 					q_bp->b_error = EIO;
Index: bus/cam/scsi/scsi_sa.c
===================================================================
RCS file: /a/dcvs/src/sys/bus/cam/scsi/scsi_sa.c,v
retrieving revision 1.21
diff -u -p -r1.21 scsi_sa.c
--- bus/cam/scsi/scsi_sa.c	22 Dec 2006 23:12:16 -0000	1.21
+++ bus/cam/scsi/scsi_sa.c	11 Oct 2007 04:35:11 -0000
@@ -205,7 +205,7 @@ struct sa_softc {
 	sa_state	state;
 	sa_flags	flags;
 	sa_quirks	quirks;
-	struct		bio_queue_head bio_queue;
+	bio_queue_head_t bio_queue;
 	int		queue_count;
 	struct		devstat device_stats;
 	int		blk_gran;
@@ -740,7 +740,7 @@ 	
 	/*
 	 * Place it at the end of the queue.
 	 */
-	bioq_insert_tail(&softc->bio_queue, bio);
+	bioq_insert_tail(softc->bio_queue, bio);
 
 	softc->queue_count++;
 	CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("sastrategy: enqueuing a %d "
@@ -1335,8 +1335,7 @@ 	 * Return all queued I/O with ENXIO.
 	 * XXX Handle any transactions queued to the card
 	 *     with XPT_ABORT_CCB.
 	 */
-	while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){
-		bioq_remove(&softc->bio_queue, q_bio);
+	while ((q_bio = bioq_remove_first(softc->bio_queue)) != NULL){
 		q_bp = q_bio->bio_buf;
 		q_bp->b_resid = q_bp->b_bcount;
 		q_bp->b_error = ENXIO;
@@ -1541,7 +1540,6 @@ 		/*
 		 * See if there is a buf with work for us to do..
 		 */
 		crit_enter();
-		bio = bioq_first(&softc->bio_queue);
 		if (periph->immediate_priority <= periph->pinfo.priority) {
 			CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
 					("queuing for immediate ccb\n"));
@@ -1551,121 +1549,125 @@ 					  periph_links.sle);
 			periph->immediate_priority = CAM_PRIORITY_NONE;
 			crit_exit();
 			wakeup(&periph->ccb_list);
-		} else if (bio == NULL) {
-			crit_exit();
-			xpt_release_ccb(start_ccb);
-		} else if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) {
-			struct bio *done_bio;
+		} else {
+			bio = bioq_remove_first(softc->bio_queue);
+			if (bio == NULL) {
+				crit_exit();
+				xpt_release_ccb(start_ccb);
+			} else if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) {
+				struct bio *done_bio;
 again:
-			softc->queue_count--;
-			bioq_remove(&softc->bio_queue, bio);
-			bp = bio->bio_buf;
-			bp->b_resid = bp->b_bcount;
-			done_bio = bio;
-			if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) {
-				/*
-				 * We now just clear errors in this case
-				 * and let the residual be the notifier.
-				 */
-				bp->b_error = 0;
-			} else if ((softc->flags & SA_FLAG_EOF_PENDING) != 0) {
+				softc->queue_count--;
+				bp = bio->bio_buf;
+				bp->b_resid = bp->b_bcount;
+				done_bio = bio;
+				if (softc->flags & SA_FLAG_EOM_PENDING) {
+					/*
+					 * We now just clear errors in this case
+					 * and let the residual be the notifier.
+					 */
+					bp->b_error = 0;
+				} else if (softc->flags & SA_FLAG_EOF_PENDING) {
+					/*
+					 * This can only happen if we're reading
+					 * in fixed length mode. In this case,
+					 * we dump the rest of the list the
+					 * same way.
+					 */
+					bp->b_error = 0;
+					if (!bioq_empty(softc->bio_queue)) {
+						biodone(done_bio);
+						bio = bioq_remove_first(
+						    softc->bio_queue);
+						goto again;
+					}
+				} else if (softc->flags & SA_FLAG_EIO_PENDING) {
+					bp->b_error = EIO;
+					bp->b_flags |= B_ERROR;
+				}
+
 				/*
-				 * This can only happen if we're reading
-				 * in fixed length mode. In this case,
-				 * we dump the rest of the list the
-				 * same way.
+				 * Only if we have no other buffers queued up
+				 * do we clear the pending error flag.
 				 */
-				bp->b_error = 0;
-				if (bioq_first(&softc->bio_queue) != NULL) {
-					biodone(done_bio);
-					goto again;
-				}
-			} else if ((softc->flags & SA_FLAG_EIO_PENDING) != 0) {
-				bp->b_error = EIO;
-				bp->b_flags |= B_ERROR;
-			}
-			bio = bioq_first(&softc->bio_queue);
-			/*
-			 * Only if we have no other buffers queued up
-			 * do we clear the pending error flag.
-			 */
-			if (bio == NULL)
-				softc->flags &= ~SA_FLAG_ERR_PENDING;
-			CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
-			    ("sastart- ERR_PENDING now 0x%x, bio is %sNULL, "
-			    "%d more buffers queued up\n",
-			    (softc->flags & SA_FLAG_ERR_PENDING),
-			    (bio != NULL)? "not " : " ", softc->queue_count));
-			crit_exit();
-			xpt_release_ccb(start_ccb);
-			biodone(done_bio);
-		} else {
-			u_int32_t length;
+				if (bioq_empty(softc->bio_queue))
+					softc->flags &= ~SA_FLAG_ERR_PENDING;
+				CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+				    ("sastart- ERR_PENDING now 0x%x, bio is %sNULL, "
+				    "%d more buffers queued up\n",
+				    (softc->flags & SA_FLAG_ERR_PENDING),
+				    !bioq_empty(softc->bio_queue) ?
+				        "not " : " ",
+				    softc->queue_count));
+				crit_exit();
+				xpt_release_ccb(start_ccb);
+				biodone(done_bio);
+			} else {
+				u_int32_t length;
 
-			bioq_remove(&softc->bio_queue, bio);
-			bp = bio->bio_buf;
-			softc->queue_count--;
+				bp = bio->bio_buf;
+				softc->queue_count--;
 
-			if ((softc->flags & SA_FLAG_FIXED) != 0) {
-				if (softc->blk_shift != 0) {
-					length =
-					    bp->b_bcount >> softc->blk_shift;
-				} else if (softc->media_blksize != 0) {
-					length =
-					    bp->b_bcount / softc->media_blksize;
+				if ((softc->flags & SA_FLAG_FIXED) != 0) {
+					if (softc->blk_shift != 0) {
+						length =
+						    bp->b_bcount >> softc->blk_shift;
+					} else if (softc->media_blksize != 0) {
+						length =
+						    bp->b_bcount / softc->media_blksize;
+					} else {
+						bp->b_error = EIO;
+						xpt_print_path(periph->path);
+						kprintf("zero blocksize for "
+						    "FIXED length writes?\n");
+						crit_exit();
+						biodone(bio);
+						break;
+					}
+					CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+					    ("Fixed Record Count is %d\n", length));
 				} else {
-					bp->b_error = EIO;
-					xpt_print_path(periph->path);
-					kprintf("zero blocksize for "
-					    "FIXED length writes?\n");
-					crit_exit();
-					biodone(bio);
-					break;
+					length = bp->b_bcount;
+					CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
+					    ("Variable Record Count is %d\n", length));
 				}
-				CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
-				    ("Fixed Record Count is %d\n", length));
-			} else {
-				length = bp->b_bcount;
-				CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
-				    ("Variable Record Count is %d\n", length));
-			}
-			devstat_start_transaction(&softc->device_stats);
-			/*
-			 * Some people have theorized that we should
-			 * suppress illegal length indication if we are
-			 * running in variable block mode so that we don't
-			 * have to request sense every time our requested
-			 * block size is larger than the written block.
-			 * The residual information from the ccb allows
-			 * us to identify this situation anyway.  The only
-			 * problem with this is that we will not get
-			 * information about blocks that are larger than
-			 * our read buffer unless we set the block size
-			 * in the mode page to something other than 0.
-			 *
-			 * I believe that this is a non-issue. If user apps
-			 * don't adjust their read size to match our record
-			 * size, that's just life. Anyway, the typical usage
-			 * would be to issue, e.g., 64KB reads and occasionally
-			 * have to do deal with 512 byte or 1KB intermediate
-			 * records.
-			 */
-			softc->dsreg = (bp->b_cmd == BUF_CMD_READ) ?
-			    MTIO_DSREG_RD : MTIO_DSREG_WR;
-			scsi_sa_read_write(&start_ccb->csio, 0, sadone,
-			    MSG_SIMPLE_Q_TAG, (bp->b_cmd == BUF_CMD_READ) != 0,
-			    FALSE, (softc->flags & SA_FLAG_FIXED) != 0,
-			    length, bp->b_data, bp->b_bcount, SSD_FULL_SIZE,
-			    IO_TIMEOUT);
-			start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED;
-			Set_CCB_Type(start_ccb, SA_CCB_BUFFER_IO);
-			start_ccb->ccb_h.ccb_bio = bio;
-			bio = bioq_first(&softc->bio_queue);
-			crit_exit();
-			xpt_action(start_ccb);
+				devstat_start_transaction(&softc->device_stats);
+				/*
+				 * Some people have theorized that we should
+				 * suppress illegal length indication if we are
+				 * running in variable block mode so that we don't
+				 * have to request sense every time our requested
+				 * block size is larger than the written block.
+				 * The residual information from the ccb allows
+				 * us to identify this situation anyway.  The only
+				 * problem with this is that we will not get
+				 * information about blocks that are larger than
+				 * our read buffer unless we set the block size
+				 * in the mode page to something other than 0.
+				 *
+				 * I believe that this is a non-issue. If user apps
+				 * don't adjust their read size to match our record
+				 * size, that's just life. Anyway, the typical usage
+				 * would be to issue, e.g., 64KB reads and occasionally
+				 * have to do deal with 512 byte or 1KB intermediate
+				 * records.
+				 */
+				softc->dsreg = (bp->b_cmd == BUF_CMD_READ) ?
+				    MTIO_DSREG_RD : MTIO_DSREG_WR;
+				scsi_sa_read_write(&start_ccb->csio, 0, sadone,
+				    MSG_SIMPLE_Q_TAG, (bp->b_cmd == BUF_CMD_READ) != 0,
+				    FALSE, (softc->flags & SA_FLAG_FIXED) != 0,
+				    length, bp->b_data, bp->b_bcount, SSD_FULL_SIZE,
+				    IO_TIMEOUT);
+				start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED;
+				Set_CCB_Type(start_ccb, SA_CCB_BUFFER_IO);
+				start_ccb->ccb_h.ccb_bio = bio;
+				crit_exit();
+				xpt_action(start_ccb);
+			}
 		}
 		
-		if (bio != NULL) {
+		if (!bioq_empty(softc->bio_queue)) {
 			/* Have more work to do, so ensure we stay scheduled */
 			xpt_schedule(periph, 1);
 		}
@@ -1724,8 +1726,8 @@ 			 */
 
 			crit_enter();
 			softc->flags |= SA_FLAG_TAPE_FROZEN;
-			while ((q_bio = bioq_first(&softc->bio_queue)) != NULL) {
-				bioq_remove(&softc->bio_queue, q_bio);
+			while ((q_bio = bioq_remove_first(softc->bio_queue))
+			    != NULL) {
 				q_bp = q_bio->bio_buf;
 				q_bp->b_resid = q_bp->b_bcount;
 				q_bp->b_error = EIO;
Index: conf/files
===================================================================
RCS file: /a/dcvs/src/sys/conf/files,v
retrieving revision 1.191
diff -u -p -r1.191 files
+++ conf/files	18 Nov 2007 21:03:53 -0000
@@ -501,6 +501,7 @@ kern/imgact_shell.c	standard
 kern/inflate.c		optional gzip
 kern/init_main.c	standard
 kern/init_sysent.c	standard
+kern/iosched_elevator1.c standard
 kern/kern_checkpoint.c	standard
 kern/kern_sysref.c	standard
 kern/kern_ccms.c	standard
Index: config/VKERNEL
===================================================================
RCS file: /a/dcvs/src/sys/config/VKERNEL,v
retrieving revision 1.12
diff -u -p -r1.12 VKERNEL
--- config/VKERNEL	3 Sep 2007 19:24:53 -0000	1.12
+++ config/VKERNEL	18 Oct 2007 15:46:49 -0000
@@ -21,7 +21,7 @@ options		KTR_SPIN_CONTENTION
 #options	DEBUG_CRIT_SECTIONS
 
 options		QUOTA
-options		DUMMYNET
+#options		DUMMYNET
 options         IPFIREWALL              #firewall
 options		IPFIREWALL_FORWARD      #enable transparent proxy support
 options		IPFIREWALL_DEFAULT_TO_ACCEPT    #allow everything by default
Index: dev/disk/ata/ata-disk.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/ata/ata-disk.c,v
retrieving revision 1.36
diff -u -p -r1.36 ata-disk.c
--- dev/disk/ata/ata-disk.c	19 May 2007 02:39:02 -0000	1.36
+++ dev/disk/ata/ata-disk.c	17 Oct 2007 03:24:19 -0000
@@ -249,8 +249,7 @@ 	biodone(request->bio);
 	ad_free(request);
     }
     ata_dmafree(atadev);
-    while ((bio = bioq_first(&adp->bio_queue))) {
-	bioq_remove(&adp->bio_queue, bio); 
+    while ((bio = bioq_remove_first(adp->bio_queue))) {
 	bp = bio->bio_buf;
 	bp->b_error = ENXIO;
 	bp->b_flags |= B_ERROR;
@@ -316,7 +315,7 @@ 	return(0);
     }
     bio->bio_driver_info = dev;
     crit_enter();
-    bioqdisksort(&adp->bio_queue, bio);
+    bioqdisksort(adp->bio_queue, bio);
     crit_exit();
     ata_start(adp->device->channel);
     return(0);
@@ -394,11 +393,12 @@ void
 ad_start(struct ata_device *atadev)
 {
     struct ad_softc *adp = atadev->driver;
-    struct bio *bio = bioq_first(&adp->bio_queue);
+    struct bio *bio;
     struct buf *bp;
     struct ad_request *request;
     int tag = 0;
 
+    bio = bioq_remove_first(adp->bio_queue);
     if (bio == NULL)
 	return;
     bp = bio->bio_buf;
@@ -447,9 +447,6 @@ 
     /* insert in tag array */
     adp->tags[tag] = request;
 
-    /* remove from drive queue */
-    bioq_remove(&adp->bio_queue, bio); 
-
     /* link onto controller queue */
     TAILQ_INSERT_TAIL(&atadev->channel->ata_queue, request, chain);
 }
Index: dev/disk/ata/ata-disk.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/ata/ata-disk.h,v
retrieving revision 1.8
diff -u -p -r1.8 ata-disk.h
--- dev/disk/ata/ata-disk.h	15 May 2007 20:29:16 -0000	1.8
+++ dev/disk/ata/ata-disk.h	11 Oct 2007 04:35:45 -0000
@@ -70,7 +70,7 @@ #define		AD_F_RAID_SUBDISK	0x0010
 
     struct ad_request		*tags[32];	/* tag array of requests */
     int				outstanding;	/* tags not serviced yet */
-    struct bio_queue_head	bio_queue;	/* head of request queue */
+    bio_queue_head_t		bio_queue;	/* head of request queue */
     struct devstat		stats;		/* devstat entry */
     struct disk			disk;		/* disklabel/slice stuff */
     cdev_t			dev;		/* device place holder */
Index: dev/disk/ata/atapi-cd.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/ata/atapi-cd.c,v
retrieving revision 1.36
diff -u -p -r1.36 atapi-cd.c
--- dev/disk/ata/atapi-cd.c	3 Jun 2007 03:44:16 -0000	1.36
+++ dev/disk/ata/atapi-cd.c	19 Oct 2007 03:55:44 -0000
@@ -189,8 +189,7 @@     if (cdp->changer_info) {
 	for (subdev = 0; subdev < cdp->changer_info->slots; subdev++) {
 	    if (cdp->driver[subdev] == cdp)
 		continue;
-	    while ((bio = bioq_first(&cdp->driver[subdev]->bio_queue))) {
-		bioq_remove(&cdp->driver[subdev]->bio_queue, bio);
+	    while ((bio = bioq_remove_first(cdp->driver[subdev]->bio_queue))) {
 		bio->bio_buf->b_flags |= B_ERROR;
 		bio->bio_buf->b_error = ENXIO;
 		biodone(bio);
@@ -209,7 +208,7 @@ 	}
 	kfree(cdp->driver, M_ACD);
 	kfree(cdp->changer_info, M_ACD);
     }
-    while ((bio = bioq_first(&cdp->bio_queue))) {
+    while ((bio = bioq_remove_first(cdp->bio_queue))) {
 	bio->bio_buf->b_flags |= B_ERROR;
 	bio->bio_buf->b_error = ENXIO;
 	biodone(bio);
@@ -1092,7 +1091,7 @@     bio->bio_driver_info = dev;
     bp->b_resid = bp->b_bcount;
 
     crit_enter();
-    bioqdisksort(&cdp->bio_queue, bio);
+    bioqdisksort(cdp->bio_queue, bio);
     crit_exit();
     ata_start(cdp->device->channel);
     return(0);
@@ -1102,16 +1101,15 @@ void 
 acd_start(struct ata_device *atadev)
 {
     struct acd_softc *cdp = atadev->driver;
-    struct bio *bio = bioq_first(&cdp->bio_queue);
+    struct bio *bio = bioq_first(cdp->bio_queue);
     struct buf *bp;
     cdev_t dev;
     u_int32_t lba, lastlba, count;
     int8_t ccb[16];
     int track, blocksize;
+    int i;
 
-    if (cdp->changer_info) {
-	int i;
-
+    if (cdp->changer_info != NULL) {
 	cdp = cdp->driver[cdp->changer_info->current_slot];
 	bio = bioq_first(&cdp->bio_queue);
 
@@ -1119,7 +1117,7 @@ 	/* check for work pending on any other 
 	for (i = 0; i < cdp->changer_info->slots; i++) {
 	    if (i == cdp->changer_info->current_slot)
 		continue;
-	    if (bioq_first(&(cdp->driver[i]->bio_queue))) {
+	    if (!bioq_empty(cdp->driver[i]->bio_queue)) {
 		if (bio == NULL || time_second > (cdp->timestamp + 10)) {
 		    acd_select_slot(cdp->driver[i]);
 		    return;
@@ -1129,7 +1127,7 @@ 	}
     }
     if (bio == NULL)
 	return;
-    bioq_remove(&cdp->bio_queue, bio);
+    bioq_remove(cdp->bio_queue, bio);
     dev = bio->bio_driver_info;
     bp = bio->bio_buf;
 
Index: dev/disk/ata/atapi-cd.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/ata/atapi-cd.h,v
retrieving revision 1.5
diff -u -p -r1.5 atapi-cd.h
--- dev/disk/ata/atapi-cd.h	17 May 2007 17:44:27 -0000	1.5
+++ dev/disk/ata/atapi-cd.h	11 Oct 2007 04:36:28 -0000
@@ -311,7 +311,7 @@     int				lun;		/* logical device unit 
     int				flags;		/* device state flags */
 #define		F_LOCKED		0x0001	/* this unit is locked */
 
-    struct bio_queue_head	bio_queue;	/* queue of i/o requests */
+    bio_queue_head_t		bio_queue;	/* queue of i/o requests */
     TAILQ_HEAD(, acd_devlist)	dev_list;	/* list of "track" devices */
     struct toc			toc;		/* table of disc contents */
     struct audiopage		au;		/* audio page info */
Index: dev/disk/ata/atapi-fd.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/ata/atapi-fd.c,v
retrieving revision 1.21
diff -u -p -r1.21 atapi-fd.c
--- dev/disk/ata/atapi-fd.c	15 May 2007 00:01:03 -0000	1.21
+++ dev/disk/ata/atapi-fd.c	11 Oct 2007 04:36:42 -0000
@@ -125,8 +125,7 @@     struct afd_softc *fdp = atadev->driv
     struct bio *bio;
     struct buf *bp;
     
-    while ((bio = bioq_first(&fdp->bio_queue))) {
-	bioq_remove(&fdp->bio_queue, bio);
+    while ((bio = bioq_remove_first(fdp->bio_queue))) {
 	bp = bio->bio_buf;
 	bp->b_flags |= B_ERROR;
 	bp->b_error = ENXIO;
@@ -314,7 +313,7 @@ 	return(0);
     }
 
     crit_enter();
-    bioqdisksort(&fdp->bio_queue, bio);
+    bioqdisksort(fdp->bio_queue, bio);
     crit_exit();
     ata_start(fdp->device->channel);
     return(0);
@@ -324,7 +323,7 @@ void 
 afd_start(struct ata_device *atadev)
 {
     struct afd_softc *fdp = atadev->driver;
-    struct bio *bio = bioq_first(&fdp->bio_queue);
+    struct bio *bio = bioq_remove_first(fdp->bio_queue);
     struct buf *bp;
     u_int32_t lba;
     u_int16_t count;
@@ -334,7 +333,6 @@ 
     if (bio == NULL)
 	return;
 
-    bioq_remove(&fdp->bio_queue, bio);
     bp = bio->bio_buf;
 
     /* should reject all queued entries if media have changed. */
Index: dev/disk/ata/atapi-fd.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/ata/atapi-fd.h,v
retrieving revision 1.4
diff -u -p -r1.4 atapi-fd.h
--- dev/disk/ata/atapi-fd.h	10 Sep 2006 01:26:33 -0000	1.4
+++ dev/disk/ata/atapi-fd.h	11 Oct 2007 04:36:54 -0000
@@ -72,7 +72,7 @@ 
 struct afd_softc {
     struct ata_device		*device;	/* device softc */
     int				lun;		/* logical device unit */
-    struct bio_queue_head	bio_queue;	/* queue of i/o requests */
+    bio_queue_head_t		bio_queue;	/* queue of i/o requests */
     struct afd_cappage		cap;		/* capabilities page info */
     struct disk			disk;		/* virtual drives */
     struct devstat		stats;
Index: dev/disk/ata/atapi-tape.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/ata/atapi-tape.c,v
retrieving revision 1.21
diff -u -p -r1.21 atapi-tape.c
--- dev/disk/ata/atapi-tape.c	19 May 2007 00:52:00 -0000	1.21
+++ dev/disk/ata/atapi-tape.c	11 Oct 2007 04:39:26 -0000
@@ -150,8 +150,7 @@     struct ast_softc *stp = atadev->driv
     struct buf *bp;
     struct bio *bio;
     
-    while ((bio = bioq_first(&stp->bio_queue))) {
-	bioq_remove(&stp->bio_queue, bio);
+    while ((bio = bioq_remove_first(stp->bio_queue))) {
 	bp = bio->bio_buf;
 	bp->b_flags |= B_ERROR;
 	bp->b_error = ENXIO;
@@ -460,7 +459,7 @@ 	}
     }
 
     crit_enter();
-    bioq_insert_tail(&stp->bio_queue, bio);
+    bioq_insert_tail(stp->bio_queue, bio);
     crit_exit();
     ata_start(stp->device->channel);
     return(0);
@@ -470,7 +469,7 @@ void 
 ast_start(struct ata_device *atadev)
 {
     struct ast_softc *stp = atadev->driver;
-    struct bio *bio = bioq_first(&stp->bio_queue);
+    struct bio *bio = bioq_remove_first(stp->bio_queue);
     struct buf *bp;
     u_int32_t blkcount;
     int8_t ccb[16];
@@ -484,8 +483,7 @@     if (bp->b_cmd == BUF_CMD_READ)
 	ccb[0] = ATAPI_READ;
     else
 	ccb[0] = ATAPI_WRITE;
-    
-    bioq_remove(&stp->bio_queue, bio);
+
     blkcount = bp->b_bcount / stp->blksize;
 
     ccb[1] = 1;
Index: dev/disk/ata/atapi-tape.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/ata/atapi-tape.h,v
retrieving revision 1.4
diff -u -p -r1.4 atapi-tape.h
--- dev/disk/ata/atapi-tape.h	17 Feb 2006 19:17:54 -0000	1.4
+++ dev/disk/ata/atapi-tape.h	11 Oct 2007 04:39:48 -0000
@@ -155,7 +155,7 @@ #define		F_FM_WRITTEN		0x0008	/* filemar
 #define		F_ONSTREAM		0x0100	/* OnStream ADR device */
 
     int				blksize;	/* block size (512 | 1024) */
-    struct bio_queue_head	bio_queue;	/* queue of i/o requests */
+    bio_queue_head_t		bio_queue;	/* queue of i/o requests */
     struct atapi_params		*param;		/* drive parameters table */
     struct ast_cappage		cap;		/* capabilities page info */
     struct devstat		stats;		/* devstat entry */
Index: dev/disk/fd/fd.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/fd/fd.c,v
retrieving revision 1.41
diff -u -p -r1.41 fd.c
--- dev/disk/fd/fd.c	23 Oct 2007 03:04:49 -0000	1.41
+++ dev/disk/fd/fd.c	18 Nov 2007 21:04:05 -0000
@@ -1504,7 +1504,7 @@ 		}
 	}
 	crit_enter();
 	bio->bio_driver_info = dev;
-	bioqdisksort(&fdc->bio_queue, bio);
+	bioqdisksort(fdc->bio_queue, bio);
 	callout_stop(&fd->toffhandle);
 
 	/* Tell devstat we are starting on the transaction */
@@ -1641,11 +1641,9 @@ 	cdev_t dev;
 
 	bio = fdc->bio;
 	if (bio == NULL) {
-		bio = bioq_first(&fdc->bio_queue);
-		if (bio != NULL) {
-			bioq_remove(&fdc->bio_queue, bio);
+		bio = bioq_remove_first(fdc->bio_queue);
+		if (bio != NULL)
 			fdc->bio = bio;
-		}
 	}
 	if (bio == NULL) {
 		/***********************************************\
Index: dev/disk/fd/fdc.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/fd/fdc.h,v
retrieving revision 1.7
diff -u -p -r1.7 fdc.h
--- dev/disk/fd/fdc.h	21 May 2007 04:22:23 -0000	1.7
+++ dev/disk/fd/fdc.h	11 Oct 2007 04:40:26 -0000
@@ -65,7 +65,7 @@ 	int	fdout;		/* mirror of the w/o digita
 	u_int	status[7];	/* copy of the registers */
 	enum	fdc_type fdct;	/* chip version of FDC */
 	int	fdc_errs;	/* number of logged errors */
-	struct	bio_queue_head bio_queue;
+	bio_queue_head_t bio_queue;
 	struct	bio *bio;	/* active buffer */
 	int	dma_overruns;	/* number of DMA overruns */
 	struct	resource *res_ioport, *res_ctl, *res_irq, *res_drq;
Index: dev/disk/md/md.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/disk/md/md.c,v
retrieving revision 1.18
diff -u -p -r1.18 md.c
--- dev/disk/md/md.c	5 Sep 2007 05:28:32 -0000	1.18
+++ dev/disk/md/md.c	11 Oct 2007 04:46:56 -0000
@@ -68,7 +68,7 @@ 
 struct md_s {
 	int unit;
 	struct devstat stats;
-	struct bio_queue_head bio_queue;
+	bio_queue_head_t bio_queue;
 	struct disk disk;
 	cdev_t dev;
 	int busy;
@@ -171,7 +171,7 @@ 	sc = dev->si_drv1;
 
 	crit_enter();
 
-	bioqdisksort(&sc->bio_queue, bio);
+	bioqdisksort(sc->bio_queue, bio);
 
 	if (sc->busy) {
 		crit_exit();
@@ -181,13 +181,12 @@ 
 	sc->busy++;
 	
 	while (1) {
-		bio = bioq_first(&sc->bio_queue);
+		bio = bioq_remove_first(sc->bio_queue);
 		if (bio == NULL) {
 			crit_exit();
 			break;
 		}
 		crit_exit();
-		bioq_remove(&sc->bio_queue, bio);
 		bp = bio->bio_buf;
 
 		devstat_start_transaction(&sc->stats);
@@ -313,7 +312,7 @@ 	sc = dev->si_drv1;
 
 	crit_enter();
 
-	bioqdisksort(&sc->bio_queue, bio);
+	bioqdisksort(sc->bio_queue, bio);
 
 	if (sc->busy) {
 		crit_exit();
@@ -323,9 +322,7 @@ 
 	sc->busy++;
 	
 	while (1) {
-		bio = bioq_first(&sc->bio_queue);
-		if (bio)
-			bioq_remove(&sc->bio_queue, bio);
+		bio = bioq_remove_first(sc->bio_queue);
 		crit_exit();
 		if (bio == NULL)
 			break;
Index: dev/raid/aac/aacvar.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/aac/aacvar.h,v
retrieving revision 1.17
diff -u -p -r1.17 aacvar.h
--- dev/raid/aac/aacvar.h	15 May 2007 22:44:08 -0000	1.17
+++ dev/raid/aac/aacvar.h	11 Oct 2007 04:40:55 -0000
@@ -325,7 +325,7 @@ 						 * controller resources */
 	TAILQ_HEAD(,aac_command) aac_busy;
 	TAILQ_HEAD(,aac_command) aac_complete;	/* commands which have been
 						 * returned by the controller */
-	struct bio_queue_head	aac_bioq;
+	bio_queue_head_t	aac_bioq;
 	struct aac_queue_table	*aac_queues;
 	struct aac_queue_entry	*aac_qentries[AAC_QUEUE_COUNT];
 
@@ -566,10 +566,8 @@ {
 	struct bio *bio;
 
 	crit_enter();
-	if ((bio = bioq_first(&sc->aac_bioq)) != NULL) {
-		bioq_remove(&sc->aac_bioq, bio);
+	if ((bio = bioq_remove_first(&sc->aac_bioq)) != NULL)
 		AACQ_REMOVE(sc, AACQ_BIO);
-	}
 	crit_exit();
 	return(bio);
 }
Index: dev/raid/amr/amrvar.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/amr/amrvar.h,v
retrieving revision 1.10
diff -u -p -r1.10 amrvar.h
--- dev/raid/amr/amrvar.h	15 May 2007 22:44:09 -0000	1.10
+++ dev/raid/amr/amrvar.h	11 Oct 2007 04:41:40 -0000
@@ -190,8 +190,8 @@ #define AMR_STATE_INTEN		(1<<2)
 #define AMR_STATE_SHUTDOWN	(1<<3)
 
     /* per-controller queues */
-    struct bio_queue_head 	amr_bioq;		/* pending I/O with no commands */
-    TAILQ_HEAD(,amr_command)	amr_ready;		/* commands ready to be submitted */
+    bio_queue_head_t	 	amr_bioq;   /* pending I/O with no commands */
+    TAILQ_HEAD(,amr_command)	amr_ready;  /* commands ready to be submitted */
     struct amr_command		*amr_busycmd[AMR_MAXCMD];
     int				amr_busyslots;
     TAILQ_HEAD(,amr_command)	amr_completed;
@@ -285,10 +285,7 @@ amr_dequeue_bio(struct amr_softc *sc)
 {
     struct bio	*bio;
 
-    crit_enter();
-    if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
-	bioq_remove(&sc->amr_bioq, bio);
-    crit_exit();
+    bio = bioq_remove_first(&sc->amr_bioq);
     return(bio);
 }
 
Index: dev/raid/ida/ida.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/ida/ida.c,v
retrieving revision 1.16
diff -u -p -r1.16 ida.c
--- dev/raid/ida/ida.c	15 May 2007 22:44:10 -0000	1.16
+++ dev/raid/ida/ida.c	11 Oct 2007 04:41:50 -0000
@@ -371,7 +371,7 @@ 
 void
 ida_submit_buf(struct ida_softc *ida, struct bio *bio)
 {
-        bioq_insert_tail(&ida->bio_queue, bio);
+        bioq_insert_tail(ida->bio_queue, bio);
         ida_construct_qcb(ida);
 	ida_start(ida);
 }
@@ -385,7 +385,7 @@ 	bus_dmasync_op_t op;
 	struct buf *bp;
 	struct bio *bio;
 
-	bio = bioq_first(&ida->bio_queue);
+	bio = bioq_remove_first(ida->bio_queue);
 	if (bio == NULL)
 		return;				/* no more buffers */
 
@@ -393,7 +393,6 @@ 	qcb = ida_get_qcb(ida);
 	if (qcb == NULL)
 		return;				/* out of resources */
 
-	bioq_remove(&ida->bio_queue, bio);
 	qcb->bio = bio;
 	qcb->flags = 0;
 
Index: dev/raid/ida/idavar.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/ida/idavar.h,v
retrieving revision 1.4
diff -u -p -r1.4 idavar.h
--- dev/raid/ida/idavar.h	15 May 2007 22:44:10 -0000	1.4
+++ dev/raid/ida/idavar.h	11 Oct 2007 04:42:20 -0000
@@ -157,7 +157,7 @@ 	struct		ida_hardware_qcb *hwqcbs;	/* HW
 	struct		ida_qcb *qcbs;			/* kernel QCB array */
 	SLIST_HEAD(, ida_qcb)	free_qcbs;	
 	STAILQ_HEAD(, ida_qcb) 	qcb_queue;
-	struct		bio_queue_head bio_queue;
+	bio_queue_head_t bio_queue;
 
 	struct		ida_access cmd;
 };
Index: dev/raid/ips/ips.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/ips/ips.h,v
retrieving revision 1.13
diff -u -p -r1.13 ips.h
--- dev/raid/ips/ips.h	22 Dec 2006 23:26:23 -0000	1.13
+++ dev/raid/ips/ips.h	11 Oct 2007 04:42:47 -0000
@@ -448,7 +448,7 @@ 	void			(*ips_poll_cmd)(ips_command_t *c
 	ips_copper_queue_t	*copper_queue;
 
 	struct lock		queue_lock;
-	struct bio_queue_head   bio_queue;
+	bio_queue_head_t	bio_queue;
 } ips_softc_t;
 
 /* function defines from ips_ioctl.c */
Index: dev/raid/ips/ips_commands.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/ips/ips_commands.c,v
retrieving revision 1.13
diff -u -p -r1.13 ips_commands.c
--- dev/raid/ips/ips_commands.c	22 Dec 2006 23:26:23 -0000	1.13
+++ dev/raid/ips/ips_commands.c	11 Oct 2007 04:42:53 -0000
@@ -189,12 +189,11 @@ {
 	ips_command_t *command;
 	struct bio *bio;
 
-	bio = bioq_first(&sc->bio_queue);
+	bio = bioq_remove_first(sc->bio_queue);
 	if (bio == NULL)
 		return;
 	if (ips_get_free_cmd(sc, &command, 0) != 0)
 		return;
-	bioq_remove(&sc->bio_queue, bio);
 	ips_send_io_request(command, bio);
 }
 
Index: dev/raid/ips/ips_disk.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/ips/ips_disk.c,v
retrieving revision 1.13
diff -u -p -r1.13 ips_disk.c
--- dev/raid/ips/ips_disk.c	17 Jun 2007 23:50:16 -0000	1.13
+++ dev/raid/ips/ips_disk.c	11 Oct 2007 04:42:56 -0000
@@ -140,7 +140,7 @@ 	DEVICE_PRINTF(8, dsc->dev, "in strategy
 	bio->bio_driver_info = dsc;
 	devstat_start_transaction(&dsc->stats);
 	lockmgr(&dsc->sc->queue_lock, LK_EXCLUSIVE|LK_RETRY);
-	bioq_insert_tail(&dsc->sc->bio_queue, bio);
+	bioq_insert_tail(dsc->sc->bio_queue, bio);
 	ips_start_io_request(dsc->sc);
 	lockmgr(&dsc->sc->queue_lock, LK_RELEASE);
 	return(0);
Index: dev/raid/mlx/mlx.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/mlx/mlx.c,v
retrieving revision 1.24
diff -u -p -r1.24 mlx.c
--- dev/raid/mlx/mlx.c	22 Dec 2006 23:26:24 -0000	1.24
+++ dev/raid/mlx/mlx.c	19 Oct 2007 03:57:05 -0000
@@ -691,7 +691,7 @@ {
     debug_called(1);
 
     crit_enter();
-    bioq_insert_tail(&sc->mlx_bioq, bio);
+    bioq_insert_tail(sc->mlx_bioq, bio);
     sc->mlx_waitbufs++;
     crit_exit();
     mlx_startio(sc);
@@ -1734,7 +1734,7 @@     crit_enter();
     for (;;) {
 
 	/* see if there's work to be done */
-	if ((bio = bioq_first(&sc->mlx_bioq)) == NULL)
+	if (bioq_empty(sc->mlx_bioq))
 	    break;
 	/* get a command */
 	if ((mc = mlx_alloccmd(sc)) == NULL)
@@ -1745,7 +1745,11 @@ 	    mlx_releasecmd(mc);
 	    break;
 	}
 	/* get the buf containing our work */
-	bioq_remove(&sc->mlx_bioq, bio);
+	if ((bio = bioq_remove_first(sc->mlx_bioq)) == NULL) {
+	    mlx_releasecmd(mc);
+	    /* release slot? XXX */
+	    break;
+	}
 	bp = bio->bio_buf;
 	sc->mlx_waitbufs--;
 	crit_exit();
Index: dev/raid/mlx/mlx_compat.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/mlx/mlx_compat.h,v
retrieving revision 1.7
diff -u -p -r1.7 mlx_compat.h
--- dev/raid/mlx/mlx_compat.h	30 Apr 2006 17:22:16 -0000	1.7
+++ dev/raid/mlx/mlx_compat.h	19 Oct 2007 04:02:36 -0000
@@ -38,7 +38,7 @@ # include <sys/proc.h>			/* old buf styl
 # include <sys/buf.h>			/* old buf style */
 # include <sys/buf2.h>
 typedef struct bio			mlx_bio;
-typedef struct bio_queue_head		mlx_bioq;
+typedef bio_queue_head_t		mlx_bioq;
 #else
 # include <sys/bio.h>
 typedef struct bio			mlx_bio;
Index: dev/raid/pst/pst-raid.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/pst/pst-raid.c,v
retrieving revision 1.24
diff -u -p -r1.24 pst-raid.c
--- dev/raid/pst/pst-raid.c	11 Jul 2007 23:46:58 -0000	1.24
+++ dev/raid/pst/pst-raid.c	11 Oct 2007 04:43:42 -0000
@@ -73,7 +73,7 @@     struct i2o_bsa_device	*info;
     cdev_t			device;
     struct devstat		stats;
     struct disk			disk;
-    struct bio_queue_head	bio_queue;
+    bio_queue_head_t		bio_queue;
     int				outstanding;
 };
 
@@ -222,7 +222,7 @@ {
     struct pst_softc *psc = ap->a_head.a_dev->si_drv1;
 
     crit_enter();
-    bioqdisksort(&psc->bio_queue, ap->a_bio);
+    bioqdisksort(psc->bio_queue, ap->a_bio);
     pst_start(psc);
     crit_exit();
     return(0);
@@ -237,7 +237,7 @@     struct bio *bio;
     u_int32_t mfa;
 
     if (psc->outstanding < (I2O_IOP_OUTBOUND_FRAME_COUNT - 1) &&
-	(bio = bioq_first(&psc->bio_queue))) {
+	(bio = bioq_remove_first(psc->bio_queue))) {
 	if ((mfa = iop_get_mfa(psc->iop)) != 0xffffffff) {
 	    request = kmalloc(sizeof(struct pst_request),
 			       M_PSTRAID, M_INTWAIT | M_ZERO);
@@ -248,7 +248,6 @@ 	    request->bio = bio;
 	    callout_init(&request->timeout);
 	    if (!dumping)
 	        callout_reset(&request->timeout, 10 * hz, pst_timeout, request);
-	    bioq_remove(&psc->bio_queue, bio);
 	    bp = bio->bio_buf;
 	    devstat_start_transaction(&psc->stats);
 	    if (pst_rw(request)) {
Index: dev/raid/twe/twe_compat.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/twe/twe_compat.h,v
retrieving revision 1.16
diff -u -p -r1.16 twe_compat.h
--- dev/raid/twe/twe_compat.h	25 Oct 2006 20:56:01 -0000	1.16
+++ dev/raid/twe/twe_compat.h	19 Oct 2007 03:59:28 -0000
@@ -158,15 +158,11 @@ # include <sys/buf.h>			/* old buf style
 # include <sys/buf2.h>  		/* bufq stuff */
 #define FREEBSD_4
 typedef struct bio			twe_bio;
-typedef struct bio_queue_head		twe_bioq;
+typedef bio_queue_head_t		twe_bioq;
 #else
 # include <sys/bio.h>
 typedef struct bio			twe_bio;
-typedef struct bio_queue_head		twe_bioq;
-# define TWE_BIO_QINIT(bq)		bioq_init(&bq);
-# define TWE_BIO_QINSERT(bq, bp)	bioq_insert_tail(&bq, bp)
-# define TWE_BIO_QFIRST(bq)		bioq_first(&bq)
-# define TWE_BIO_QREMOVE(bq, bp)	bioq_remove(&bq, bp)
+typedef bio_queue_head_t		twe_bioq;
 # define TWE_BIO_IS_READ(bp)		((bp)->bio_cmd == BIO_READ)
 # define TWE_BIO_DATA(bp)		(bp)->bio_data
 # define TWE_BIO_LENGTH(bp)		(bp)->bio_bcount
Index: dev/raid/twe/twevar.h
===================================================================
RCS file: /a/dcvs/src/sys/dev/raid/twe/twevar.h,v
retrieving revision 1.10
diff -u -p -r1.10 twevar.h
--- dev/raid/twe/twevar.h	15 May 2007 22:44:11 -0000	1.10
+++ dev/raid/twe/twevar.h	19 Oct 2007 04:00:03 -0000
@@ -281,7 +281,7 @@ static __inline void
 twe_enqueue_bio(struct twe_softc *sc, struct bio *bio)
 {
     crit_enter();
-    bioq_insert_tail(&sc->twe_bioq, bio);
+    bioq_insert_tail(sc->twe_bioq, bio);
     TWEQ_ADD(sc, TWEQ_BIO);
     crit_exit();
 }
@@ -293,10 +293,8 @@ {
     struct bio *bio;
 
     crit_enter();
-    if ((bio = bioq_first(&sc->twe_bioq)) != NULL) {
-	bioq_remove(&sc->twe_bioq, bio);
+    if ((bio = bioq_remove_first(sc->twe_bioq)) != NULL)
 	TWEQ_REMOVE(sc, TWEQ_BIO);
-    }
     crit_exit();
     return(bio);
 }
Index: dev/virtual/cdrom/vcd.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/virtual/cdrom/vcd.c,v
retrieving revision 1.1
diff -u -p -r1.1 vcd.c
--- dev/virtual/cdrom/vcd.c	25 May 2007 02:21:13 -0000	1.1
+++ dev/virtual/cdrom/vcd.c	11 Oct 2007 04:44:11 -0000
@@ -54,7 +54,7 @@ #include <sys/stat.h>
 #include <unistd.h>
 
 struct vcd_softc {
-	struct bio_queue_head bio_queue;
+	bio_queue_head_t bio_queue;
 	struct devstat stats;
 	struct disk disk;
 	cdev_t dev;
@@ -148,9 +148,8 @@ 
 	dev = ap->a_head.a_dev;
 	sc = dev->si_drv1;
 
-	bioqdisksort(&sc->bio_queue, bio);
-	while ((bio = bioq_first(&sc->bio_queue)) != NULL) {
-		bioq_remove(&sc->bio_queue, bio);
+	bioqdisksort(sc->bio_queue, bio);
+	while ((bio = bioq_remove_first(sc->bio_queue)) != NULL) {
 		bp = bio->bio_buf;
 
 		devstat_start_transaction(&sc->stats);
Index: dev/virtual/disk/vdisk.c
===================================================================
RCS file: /a/dcvs/src/sys/dev/virtual/disk/vdisk.c,v
retrieving revision 1.7
diff -u -p -r1.7 vdisk.c
--- dev/virtual/disk/vdisk.c	2 Jul 2007 17:15:10 -0000	1.7
+++ dev/virtual/disk/vdisk.c	18 Oct 2007 22:46:40 -0000
@@ -55,7 +55,7 @@ #include <sys/stat.h>
 #include <unistd.h>
 
 struct vkd_softc {
-	struct bio_queue_head bio_queue;
+	bio_queue_head_t bio_queue;
 	struct devstat stats;
 	struct disk disk;
 	struct spinlock spin;
@@ -160,13 +160,12 @@ 	sc = dev->si_drv1;
 
 	if (sc->iotd) {
 		spin_lock_wr(&sc->spin);
-		bioqdisksort(&sc->bio_queue, bio);
+		bioqdisksort(sc->bio_queue, bio);
 		spin_unlock_wr(&sc->spin);
 		wakeup(sc->iotd);
 	} else {
-		bioqdisksort(&sc->bio_queue, bio);
-		while ((bio = bioq_first(&sc->bio_queue)) != NULL) {
-			bioq_remove(&sc->bio_queue, bio);
+		bioqdisksort(sc->bio_queue, bio);
+		while ((bio = bioq_remove_first(sc->bio_queue)) != NULL) {
 			vkd_doio(sc, bio);
 			biodone(bio);
 		}
@@ -189,8 +188,7 @@ 	kprintf("vkd%d I/O helper on cpu %d\n",
 
 	spin_lock_wr(&sc->spin);
 	for (;;) {
-		while ((bio = bioq_first(&sc->bio_queue)) != NULL) {
-			bioq_remove(&sc->bio_queue, bio);
+		while ((bio = bioq_remove_first(sc->bio_queue)) != NULL) {
 			spin_unlock_wr(&sc->spin);
 			vkd_doio(sc, bio);
 			get_mplock();
Index: kern/iosched_elevator1.c
===================================================================
RCS file: kern/iosched_elevator1.c
diff -N kern/iosched_elevator1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ kern/iosched_elevator1.c	19 Nov 2007 20:04:10 -0000
@@ -0,0 +1,242 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/buf2.h>
+
+struct bio_queue_head {
+	TAILQ_HEAD(bio_queue, bio) queue;
+	off_t	last_offset;
+	struct	bio *insert_point;
+	struct	bio *switch_point;
+};
+
+static void
+dump_bio_queue_head(char *s, struct bio_queue_head *head)
+{
+	struct bio *bio;
+
+	kprintf("dump_bio_queue_head: %s\n", s);
+	TAILQ_FOREACH(bio, &head->queue, bio_act) {
+		kprintf("\t%p %lld", bio, bio->bio_offset);
+	}
+	if (!TAILQ_EMPTY(&head->queue))
+		kprintf("\n");
+	kprintf("last_offset %lld, insert_point %p, switch_point %p\n",
+		head->last_offset, head->insert_point, head->switch_point);
+}
+
+static void
+iosched_elevator1_init(bio_queue_head_t *phead)
+{
+	struct bio_queue_head *head;
+
+	head = *phead = kmalloc(sizeof(struct bio_queue_head), M_DEVBUF,
+				M_INTWAIT);
+	TAILQ_INIT(&head->queue);
+	head->last_offset = 0;
+	head->insert_point = NULL;
+	head->switch_point = NULL;
+}
+
+static struct bio *
+iosched_elevator1_first(bio_queue_head_t bqh)
+{
+	struct bio_queue_head *head = bqh;
+
+	return (TAILQ_FIRST(&head->queue));
+}
+
+static boolean_t
+iosched_elevator1_empty(bio_queue_head_t bqh)
+{
+	struct bio_queue_head *head = bqh;
+
+	return (TAILQ_EMPTY(&head->queue));
+}
+
+static void
+iosched_elevator1_insert_tail(bio_queue_head_t bqh, struct bio *bio)
+{
+	struct bio_queue_head *head = bqh;
+
+	kprintf("iosched_elevator1_insert_tail: head %p, bio %p, offset %lld, "
+		"B_ORDERED %d\n",
+		head, bio, bio->bio_offset,
+		(bio->bio_buf->b_flags & B_ORDERED) ? 1 : 0);
+
+	/* unordered inserts reset the switch point */
+	if (!(bio->bio_buf->b_flags & B_ORDERED)) {
+		head->insert_point = bio;
+		head->switch_point = NULL;
+	}
+	TAILQ_INSERT_TAIL(&head->queue, bio, bio_act);
+}
+
+static void
+iosched_elevator1_remove(bio_queue_head_t bqh, struct bio *bio)
+{
+	struct bio_queue_head *head = bqh;
+
+	if (bio == head->switch_point)	/* move switch point to next elt */
+		head->switch_point = TAILQ_NEXT(bio, bio_act);
+
+	if (bio == head->insert_point) {
+		/* move insert point to prev elt */
+		head->insert_point = TAILQ_PREV(bio, bio_queue, bio_act);
+		if (head->insert_point == NULL)
+			head->last_offset = 0;
+	} else if (bio == TAILQ_FIRST(&head->queue)) {
+		head->last_offset = bio->bio_offset;
+	}
+	TAILQ_REMOVE(&head->queue, bio, bio_act);
+
+	/* switch */
+	if (TAILQ_FIRST(&head->queue) == head->switch_point)
+		head->switch_point = NULL;
+}
+
+static struct bio *
+iosched_elevator1_remove_first(bio_queue_head_t bqh)
+{
+	struct bio_queue_head *head = bqh;
+	struct bio *first = TAILQ_FIRST(&head->queue);
+
+	if (first != NULL)
+		iosched_elevator1_remove(head, first);
+
+	return (first);
+}
+
+/*
+ * Seek sort for disks.
+ *
+ * The bio_queue keep two queues, sorted in ascending block order.  The first
+ * queue holds those requests which are positioned after the current block
+ * (in the first request); the second, which starts at queue->switch_point,
+ * holds requests which came in after their block number was passed.  Thus
+ * we implement a one way scan, retracting after reaching the end of the drive
+ * to the first request on the second queue, at which time it becomes the
+ * first queue.
+ *
+ * A one-way scan is natural because of the way UNIX read-ahead blocks are
+ * allocated.
+ */
+static void
+iosched_elevator1_io_sort(bio_queue_head_t bqh, struct bio *bio)
+{
+	struct bio_queue_head *bioq = bqh;
+	struct bio *bq, *bn, *be;
+
+	kprintf("\niosched_elevator1_io_sort: head %p, bio %p, offset %lld, "
+		"B_ORDERED %d\n",
+		bioq, bio, bio->bio_offset,
+		(bio->bio_buf->b_flags & B_ORDERED) ? 1 : 0);
+	dump_bio_queue_head("before iosched_elevator1_io_sort", bioq);
+
+	be = TAILQ_LAST(&bioq->queue, bio_queue);
+
+	/*
+	 * If the queue is empty or we are an unordered transaction,
+	 * then just insert at the end.
+	 */
+	if ((bq = TAILQ_FIRST(&bioq->queue)) == NULL || 
+	    !(bio->bio_buf->b_flags & B_ORDERED)) {
+		iosched_elevator1_insert_tail(bioq, bio);
+		dump_bio_queue_head("after iosched_elevator1_io_sort", bioq);
+		return;
+	}
+
+	if (bioq->insert_point != NULL) {
+		/*
+		 * A certain portion of the list is "locked" to preserve
+		 * ordering, so we can only insert after the insert point.
+		 */
+		bq = bioq->insert_point;
+	} else {
+		/*
+		 * If we lie before the last removed (currently active)
+		 * request, and are not inserting ourselves into the
+		 * "locked" portion of the list, then we must add ourselves
+		 * to the second request list.
+		 */
+		if (bio->bio_offset < bioq->last_offset) {
+			bq = bioq->switch_point;
+			/*
+			 * If we are starting a new secondary list,
+			 * then it's easy.
+			 */
+			if (bq == NULL) {
+				bioq->switch_point = bio;
+				iosched_elevator1_insert_tail(bioq, bio);
+				dump_bio_queue_head("after "
+						    "iosched_elevator1_io_sort",
+						    bioq);
+				return;
+			}
+			/*
+			 * If we lie ahead of the current switch point,
+			 * insert us before the switch point and move
+			 * the switch point.
+			 */
+			if (bio->bio_offset < bq->bio_offset) {
+				bioq->switch_point = bio;
+				TAILQ_INSERT_BEFORE(bq, bio, bio_act);
+				dump_bio_queue_head("after "
+						    "iosched_elevator1_io_sort",
+						    bioq);
+				return;
+			}
+		} else {
+			if (bioq->switch_point != NULL)
+				be = TAILQ_PREV(bioq->switch_point, bio_queue,
+						bio_act);
+			/*
+			 * If we lie between last_offset and bq,
+			 * insert before bq.
+			 */
+			if (bio->bio_offset < bq->bio_offset) {
+				TAILQ_INSERT_BEFORE(bq, bio, bio_act);
+				dump_bio_queue_head("after "
+						    "iosched_elevator1_io_sort",
+						    bioq);
+				return;
+			}
+		}
+	}
+
+	 * Request is at/after our current position in the list.
+	 */
+
+	/* Optimize for sequential I/O by seeing if we go at the tail. */
+	if (bio->bio_offset > be->bio_offset) {
+		TAILQ_INSERT_AFTER(&bioq->queue, be, bio, bio_act);
+		dump_bio_queue_head("after iosched_elevator1_io_sort", bioq);
+		return;
+	}
+
+	/* Otherwise, linear scan */
+	while ((bn = TAILQ_NEXT(bq, bio_act)) != NULL) {
+		/*
+		 * We want to go after the current request if the next
+		 * request is a larer cylinder than our request or if it is
+		 * the end of the first request list.
+		 */
+		if (bio->bio_offset < bn->bio_offset ||
+		    bn == bioq->switch_point)
+			break;
+		bq = bn;
+	}
+	TAILQ_INSERT_AFTER(&bioq->queue, bq, bio, bio_act);
+	dump_bio_queue_head("after iosched_elevator1_io_sort", bioq);
+}
+
+struct iosched_ops iosched_elevator1_ops = {
+	iosched_elevator1_init,
+	iosched_elevator1_empty,
+	iosched_elevator1_first,
+	iosched_elevator1_insert_tail,
+	iosched_elevator1_remove,
+	iosched_elevator1_remove_first,
+	iosched_elevator1_io_sort
+};
Index: kern/kern_exec.c
===================================================================
RCS file: /a/dcvs/src/sys/kern/kern_exec.c,v
retrieving revision 1.62
diff -u -p -r1.62 kern_exec.c
--- kern/kern_exec.c	28 Aug 2007 01:09:24 -0000	1.62
+++ kern/kern_exec.c	18 Nov 2007 21:25:50 -0000
@@ -108,7 +108,7 @@ exec_objcache_init(void *arg __unused)
 {
 	exec_objcache = objcache_create_mbacked(
 					M_EXECARGS, PATH_MAX + ARG_MAX,
-					16,	/* up to this many objects */
+					32,	/* up to this many objects */
 					2,	/* minimal magazine capacity */
 					NULL, NULL, NULL);
 }
Index: kern/subr_disk.c
===================================================================
RCS file: /a/dcvs/src/sys/kern/subr_disk.c,v
retrieving revision 1.39
diff -u -p -r1.39 subr_disk.c
--- kern/subr_disk.c	30 Jul 2007 08:02:38 -0000	1.39
+++ kern/subr_disk.c	16 Oct 2007 21:30:59 -0000
@@ -485,121 +485,14 @@ 
 	return(error);
 }
 
-
 SYSCTL_INT(_debug_sizeof, OID_AUTO, diskslices, CTLFLAG_RD, 
     0, sizeof(struct diskslices), "sizeof(struct diskslices)");
 
 SYSCTL_INT(_debug_sizeof, OID_AUTO, disk, CTLFLAG_RD, 
     0, sizeof(struct disk), "sizeof(struct disk)");
 
-
-/*
- * Seek sort for disks.
- *
- * The bio_queue keep two queues, sorted in ascending block order.  The first
- * queue holds those requests which are positioned after the current block
- * (in the first request); the second, which starts at queue->switch_point,
- * holds requests which came in after their block number was passed.  Thus
- * we implement a one way scan, retracting after reaching the end of the drive
- * to the first request on the second queue, at which time it becomes the
- * first queue.
- *
- * A one-way scan is natural because of the way UNIX read-ahead blocks are
- * allocated.
- */
-void
-bioqdisksort(struct bio_queue_head *bioq, struct bio *bio)
-{
-	struct bio *bq;
-	struct bio *bn;
-	struct bio *be;
-	
-	be = TAILQ_LAST(&bioq->queue, bio_queue);
-	/*
-	 * If the queue is empty or we are an
-	 * ordered transaction, then it's easy.
-	 */
-	if ((bq = bioq_first(bioq)) == NULL || 
-	    (bio->bio_buf->b_flags & B_ORDERED) != 0) {
-		bioq_insert_tail(bioq, bio);
-		return;
-	} else if (bioq->insert_point != NULL) {
-
-		/*
-		 * A certain portion of the list is
-		 * "locked" to preserve ordering, so
-		 * we can only insert after the insert
-		 * point.
-		 */
-		bq = bioq->insert_point;
-	} else {
-
-		/*
-		 * If we lie before the last removed (currently active)
-		 * request, and are not inserting ourselves into the
-		 * "locked" portion of the list, then we must add ourselves
-		 * to the second request list.
-		 */
-		if (bio->bio_offset < bioq->last_offset) {
-			bq = bioq->switch_point;
-			/*
-			 * If we are starting a new secondary list,
-			 * then it's easy.
-			 */
-			if (bq == NULL) {
-				bioq->switch_point = bio;
-				bioq_insert_tail(bioq, bio);
-				return;
-			}
-			/*
-			 * If we lie ahead of the current switch point,
-			 * insert us before the switch point and move
-			 * the switch point.
-			 */
-			if (bio->bio_offset < bq->bio_offset) {
-				bioq->switch_point = bio;
-				TAILQ_INSERT_BEFORE(bq, bio, bio_act);
-				return;
-			}
-		} else {
-			if (bioq->switch_point != NULL)
-				be = TAILQ_PREV(bioq->switch_point,
-						bio_queue, bio_act);
-			/*
-			 * If we lie between last_offset and bq,
-			 * insert before bq.
-			 */
-			if (bio->bio_offset < bq->bio_offset) {
-				TAILQ_INSERT_BEFORE(bq, bio, bio_act);
-				return;
-			}
-		}
-	}
-
-	/*
-	 * Request is at/after our current position in the list.
-	 * Optimize for sequential I/O by seeing if we go at the tail.
-	 */
-	if (bio->bio_offset > be->bio_offset) {
-		TAILQ_INSERT_AFTER(&bioq->queue, be, bio, bio_act);
-		return;
-	}
-
-	/* Otherwise, insertion sort */
-	while ((bn = TAILQ_NEXT(bq, bio_act)) != NULL) {
-		
-		/*
-		 * We want to go after the current request if it is the end
-		 * of the first request list, or if the next request is a
-		 * larger cylinder than our request.
-		 */
-		if (bn == bioq->switch_point
-		 || bio->bio_offset < bn->bio_offset)
-			break;
-		bq = bn;
-	}
-	TAILQ_INSERT_AFTER(&bioq->queue, bq, bio, bio_act);
-}
+extern struct iosched_ops iosched_elevator1_ops;
+struct iosched_ops *iosched = &iosched_elevator1_ops;
 
 /*
  * Disk error is the preface to plaintive error messages
@@ -700,4 +593,3 @@ 		}
 	}
 	return(NULL);
 }
-
Index: kern/vfs_bio.c
===================================================================
RCS file: /a/dcvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.95
diff -u -p -r1.95 vfs_bio.c
--- kern/vfs_bio.c	7 Nov 2007 00:46:36 -0000	1.95
+++ kern/vfs_bio.c	7 Nov 2007 20:12:16 -0000
@@ -839,7 +839,9 @@  */
 void
 bdirty(struct buf *bp)
 {
-	KASSERT(bp->b_qindex == BQUEUE_NONE, ("bdirty: buffer %p still on queue %d", bp, bp->b_qindex));
+	KASSERT(bp->b_qindex == BQUEUE_NONE,
+		("bdirty: buffer %p still on queue %d", bp, bp->b_qindex));
+
 	if (bp->b_flags & B_NOCACHE) {
 		kprintf("bdirty: clearing B_NOCACHE on buf %p\n", bp);
 		bp->b_flags &= ~B_NOCACHE;
@@ -849,7 +851,7 @@ 		kprintf("bdirty: warning, dirtying inv
 	}
 	bp->b_flags &= ~B_RELBUF;
 
-	if ((bp->b_flags & B_DELWRI) == 0) {
+	if (!(bp->b_flags & B_DELWRI)) {
 		bp->b_flags |= B_DELWRI;
 		reassignbuf(bp);
 		++numdirtybuffers;
Index: sys/buf.h
===================================================================
RCS file: /a/dcvs/src/sys/sys/buf.h,v
retrieving revision 1.41
diff -u -p -r1.41 buf.h
--- sys/buf.h	7 Nov 2007 00:46:38 -0000	1.41
+++ sys/buf.h	7 Nov 2007 20:13:34 -0000
@@ -291,13 +291,6 @@ #define BUF_WMESG "bufwait"
 
 #endif /* _KERNEL */
 
-struct bio_queue_head {
-	TAILQ_HEAD(bio_queue, bio) queue;
-	off_t	last_offset;
-	struct	bio *insert_point;
-	struct	bio *switch_point;
-};
-
 /*
  * This structure describes a clustered I/O.
  */
Index: sys/buf2.h
===================================================================
RCS file: /a/dcvs/src/sys/sys/buf2.h,v
retrieving revision 1.20
diff -u -p -r1.20 buf2.h
--- sys/buf2.h	7 Nov 2007 00:46:38 -0000	1.20
+++ sys/buf2.h	7 Nov 2007 20:13:34 -0000
@@ -144,45 +144,60 @@ #define BUF_LOCKFREE(bp) 			\
 	if (BUF_REFCNTNB(bp) > 0)		\
 		panic("free locked buf")
 
+typedef void *bio_queue_head_t;
+
+struct iosched_ops {
+	void 		(*init)(bio_queue_head_t *);
+	boolean_t	(*empty)(bio_queue_head_t);
+	struct bio *	(*first)(bio_queue_head_t);
+	void		(*insert_tail)(bio_queue_head_t, struct bio *);
+	void		(*remove)(bio_queue_head_t, struct bio *);
+	struct bio *	(*remove_first)(bio_queue_head_t);
+	void		(*io_sort)(bio_queue_head_t, struct bio *);
+};
+
+extern struct iosched_ops *iosched;
+
 static __inline void
-bioq_init(struct bio_queue_head *head)
+bioq_init(bio_queue_head_t *phead)
 {
-	TAILQ_INIT(&head->queue);
-	head->last_offset = 0;
-	head->insert_point = NULL;
-	head->switch_point = NULL;
+	iosched->init(phead);
+}
+
+static __inline boolean_t
+bioq_empty(bio_queue_head_t head)
+{
+	return (iosched->empty(head));
 }
 
 static __inline void
-bioq_insert_tail(struct bio_queue_head *head, struct bio *bio)
+bioq_insert_tail(bio_queue_head_t head, struct bio *bio)
 {
-	if ((bio->bio_buf->b_flags & B_ORDERED) != 0) {
-		head->insert_point = bio;
-		head->switch_point = NULL;
-	}
-	TAILQ_INSERT_TAIL(&head->queue, bio, bio_act);
+	iosched->insert_tail(head, bio);
 }
 
 static __inline void
-bioq_remove(struct bio_queue_head *head, struct bio *bio)
+bioq_remove(bio_queue_head_t head, struct bio *bio)
+{
+	iosched->remove(head, bio);
+}
+
+static __inline struct bio *
+bioq_first(bio_queue_head_t head)
 {
-	if (bio == head->switch_point)
-		head->switch_point = TAILQ_NEXT(bio, bio_act);
-	if (bio == head->insert_point) {
-		head->insert_point = TAILQ_PREV(bio, bio_queue, bio_act);
-		if (head->insert_point == NULL)
-			head->last_offset = 0;
-	} else if (bio == TAILQ_FIRST(&head->queue))
-		head->last_offset = bio->bio_offset;
-	TAILQ_REMOVE(&head->queue, bio, bio_act);
-	if (TAILQ_FIRST(&head->queue) == head->switch_point)
-		head->switch_point = NULL;
+	return (iosched->first(head));
 }
 
 static __inline struct bio *
-bioq_first(struct bio_queue_head *head)
+bioq_remove_first(bio_queue_head_t head)
+{
+	return (iosched->remove_first(head));
+}
+
+static __inline void
+bioqdisksort(bio_queue_head_t bioq, struct bio *bio)
 {
-	return (TAILQ_FIRST(&head->queue));
+	iosched->io_sort(bioq, bio);
 }
 
 /*
Index: sys/diskslice.h
===================================================================
RCS file: /a/dcvs/src/sys/sys/diskslice.h,v
retrieving revision 1.22
diff -u -p -r1.22 diskslice.h
--- sys/diskslice.h	19 Jun 2007 06:07:51 -0000	1.22
+++ sys/diskslice.h	16 Oct 2007 20:36:18 -0000
@@ -407,7 +407,6 @@ 
 struct buf;
 struct bio;
 struct disk_info;
-struct bio_queue_head;
 
 int	mbrinit (cdev_t dev, struct disk_info *info,
 		    struct diskslices **sspp);
@@ -435,7 +434,6 @@ 
 void	diskerr (struct bio *bio, cdev_t dev, const char *what, int pri,
 		    int donecnt);
 void	disksort (struct buf *ap, struct buf *bp);
-void	bioqdisksort (struct bio_queue_head *ap, struct bio *bio);
 
 #endif /* _KERNEL */
 
Index: vfs/mfs/mfs_vfsops.c
===================================================================
RCS file: /a/dcvs/src/sys/vfs/mfs/mfs_vfsops.c,v
retrieving revision 1.40
diff -u -p -r1.40 mfs_vfsops.c
--- vfs/mfs/mfs_vfsops.c	9 May 2007 00:53:35 -0000	1.40
+++ vfs/mfs/mfs_vfsops.c	11 Oct 2007 04:46:03 -0000
@@ -170,7 +170,7 @@ 
 	/*
 	 * Initiate I/O
 	 */
-	bioq_insert_tail(&mfsp->bio_queue, bio);
+	bioq_insert_tail(mfsp->bio_queue, bio);
 	wakeup((caddr_t)mfsp);
 	return(0);
 
@@ -414,8 +414,7 @@ 
 	while (mfsp->mfs_active) {
 		crit_enter();
 
-		while ((bio = bioq_first(&mfsp->bio_queue)) != NULL) {
-			bioq_remove(&mfsp->bio_queue, bio);
+		while ((bio = bioq_remove_first(mfsp->bio_queue)) != NULL) {
 			crit_exit();
 			bp = bio->bio_buf;
 			mfs_doio(bio, mfsp);
Index: vfs/mfs/mfs_vnops.c
===================================================================
RCS file: /a/dcvs/src/sys/vfs/mfs/mfs_vnops.c,v
retrieving revision 1.37
diff -u -p -r1.37 mfs_vnops.c
--- vfs/mfs/mfs_vnops.c	13 Aug 2007 17:31:56 -0000	1.37
+++ vfs/mfs/mfs_vnops.c	11 Oct 2007 04:46:16 -0000
@@ -214,7 +214,7 @@ 		/*
 		 * VOP from some other process, queue to MFS process and
 		 * wake it up.
 		 */
-		bioq_insert_tail(&mfsp->bio_queue, bio);
+		bioq_insert_tail(mfsp->bio_queue, bio);
 		wakeup((caddr_t)mfsp);
 	}
 	crit_exit();
@@ -324,8 +324,7 @@ 
 	/*
 	 * Finish any pending I/O requests.
 	 */
-	while ((bio = bioq_first(&mfsp->bio_queue)) != NULL) {
-		bioq_remove(&mfsp->bio_queue, bio);
+	while ((bio = bioq_remove_first(mfsp->bio_queue)) != NULL) {
 		mfs_doio(bio, mfsp);
 		wakeup((caddr_t)bio->bio_buf);
 	}
@@ -356,7 +355,7 @@ 	 * vnode, so if we find any other uses,
 	 */
 	if (vp->v_sysref.refcnt > 1)
 		kprintf("mfs_close: ref count %d > 1\n", vp->v_sysref.refcnt);
-	if (vp->v_sysref.refcnt > 1 || (bioq_first(&mfsp->bio_queue) != NULL))
+	if (vp->v_sysref.refcnt > 1 || (!bioq_empty(mfsp->bio_queue)))
 		panic("mfs_close");
 	/*
 	 * Send a request to the filesystem server to exit.
@@ -385,9 +384,9 @@ {
 	struct vnode *vp = ap->a_vp;
 	struct mfsnode *mfsp = VTOMFS(vp);
 
-	if (bioq_first(&mfsp->bio_queue) != NULL)
+	if (!bioq_empty(mfsp->bio_queue))
 		panic("mfs_inactive: not inactive (next buffer %p)",
-			bioq_first(&mfsp->bio_queue));
+			bioq_first(mfsp->bio_queue));
 	return (0);
 }
 
Index: vfs/mfs/mfsnode.h
===================================================================
RCS file: /a/dcvs/src/sys/vfs/mfs/mfsnode.h,v
retrieving revision 1.6
diff -u -p -r1.6 mfsnode.h
--- vfs/mfs/mfsnode.h	10 Sep 2006 01:26:41 -0000	1.6
+++ vfs/mfs/mfsnode.h	11 Oct 2007 04:46:27 -0000
@@ -47,7 +47,7 @@ 	struct	vnode *mfs_vnode;	/* vnode assoc
 	caddr_t	mfs_baseoff;		/* base of file system in memory */
 	long	mfs_size;		/* size of memory file system */
 	struct thread *mfs_td;		/* supporting thread */
-	struct bio_queue_head bio_queue; /* list of I/O requests */
+	bio_queue_head_t bio_queue;	/* list of I/O requests */
 	cdev_t	mfs_dev;		/* underlying device */
 	int	mfs_active;
 	long	mfs_spare[1];


[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]