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
> 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]