Adds the ability to enable / disable sorting of BIO requests queued within
CAM. This can significantly improve performance particularly for SSDs which don't suffer from seek latencies. The sysctl / tunable kern.cam.sort_io_queues provides the systems default setting where:- 0 = queued BIOs are NOT sorted 1 = queued BIOs are sorted (default) Each device gets its own sysctl kern.cam.<type>.<id>.sort_io_queue Valid values are:- -1 = use system default (default) 0 = queued BIOs are NOT sorted 1 = queued BIOs are sorted Note: Additional patch will look to add automatic use of none sorted queues for none rotating media e.g. SSD's Reviewed by: scottl Approved by: pjd (mentor) MFC after: 2 weeks
This commit is contained in:
parent
ce7ad6640c
commit
5f83aee5e5
@ -130,6 +130,7 @@ struct ada_softc {
|
||||
ada_state state;
|
||||
ada_flags flags;
|
||||
ada_quirks quirks;
|
||||
int sort_io_queue;
|
||||
int ordered_tag_count;
|
||||
int outstanding_cmds;
|
||||
int trim_max_ranges;
|
||||
@ -449,6 +450,8 @@ static void adaresume(void *arg);
|
||||
softc->read_ahead : ada_read_ahead)
|
||||
#define ADA_WC (softc->write_cache >= 0 ? \
|
||||
softc->write_cache : ada_write_cache)
|
||||
#define ADA_SIO (softc->sort_io_queue >= 0 ? \
|
||||
softc->sort_io_queue : cam_sort_io_queues)
|
||||
|
||||
/*
|
||||
* Most platforms map firmware geometry to actual, but some don't. If
|
||||
@ -670,10 +673,17 @@ adastrategy(struct bio *bp)
|
||||
* Place it in the queue of disk activities for this disk
|
||||
*/
|
||||
if (bp->bio_cmd == BIO_DELETE &&
|
||||
(softc->flags & ADA_FLAG_CAN_TRIM))
|
||||
bioq_disksort(&softc->trim_queue, bp);
|
||||
else
|
||||
bioq_disksort(&softc->bio_queue, bp);
|
||||
(softc->flags & ADA_FLAG_CAN_TRIM)) {
|
||||
if (ADA_SIO)
|
||||
bioq_disksort(&softc->trim_queue, bp);
|
||||
else
|
||||
bioq_insert_tail(&softc->trim_queue, bp);
|
||||
} else {
|
||||
if (ADA_SIO)
|
||||
bioq_disksort(&softc->bio_queue, bp);
|
||||
else
|
||||
bioq_insert_tail(&softc->bio_queue, bp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Schedule ourselves for performing the work.
|
||||
@ -999,6 +1009,10 @@ adasysctlinit(void *context, int pending)
|
||||
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
|
||||
OID_AUTO, "write_cache", CTLFLAG_RW | CTLFLAG_MPSAFE,
|
||||
&softc->write_cache, 0, "Enable disk write cache.");
|
||||
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
|
||||
OID_AUTO, "sort_io_queue", CTLFLAG_RW | CTLFLAG_MPSAFE,
|
||||
&softc->sort_io_queue, 0,
|
||||
"Sort IO queue to try and optimise disk access patterns");
|
||||
#ifdef ADA_TEST_FAILURE
|
||||
/*
|
||||
* Add a 'door bell' sysctl which allows one to set it from userland
|
||||
@ -1134,6 +1148,7 @@ adaregister(struct cam_periph *periph, void *arg)
|
||||
snprintf(announce_buf, sizeof(announce_buf),
|
||||
"kern.cam.ada.%d.write_cache", periph->unit_number);
|
||||
TUNABLE_INT_FETCH(announce_buf, &softc->write_cache);
|
||||
softc->sort_io_queue = -1;
|
||||
adagetparams(periph, cgd);
|
||||
softc->disk = disk_alloc();
|
||||
softc->disk->d_devstat = devstat_new_entry(periph->periph_name,
|
||||
|
@ -110,6 +110,15 @@ const int num_cam_status_entries =
|
||||
|
||||
#ifdef _KERNEL
|
||||
SYSCTL_NODE(_kern, OID_AUTO, cam, CTLFLAG_RD, 0, "CAM Subsystem");
|
||||
|
||||
#ifndef CAM_DEFAULT_SORT_IO_QUEUES
|
||||
#define CAM_DEFAULT_SORT_IO_QUEUES 1
|
||||
#endif
|
||||
|
||||
int cam_sort_io_queues = CAM_DEFAULT_SORT_IO_QUEUES;
|
||||
TUNABLE_INT("kern.cam.sort_io_queues", &cam_sort_io_queues);
|
||||
SYSCTL_INT(_kern_cam, OID_AUTO, sort_io_queues, CTLFLAG_RWTUN,
|
||||
&cam_sort_io_queues, 0, "Sort IO queues to try and optimise disk access patterns");
|
||||
#endif
|
||||
|
||||
void
|
||||
|
@ -228,6 +228,9 @@ struct cam_status_entry
|
||||
|
||||
extern const struct cam_status_entry cam_status_table[];
|
||||
extern const int num_cam_status_entries;
|
||||
#ifdef _KERNEL
|
||||
extern int cam_sort_io_queues;
|
||||
#endif
|
||||
union ccb;
|
||||
|
||||
#ifdef SYSCTL_DECL /* from sysctl.h */
|
||||
|
@ -145,6 +145,7 @@ struct da_softc {
|
||||
da_state state;
|
||||
da_flags flags;
|
||||
da_quirks quirks;
|
||||
int sort_io_queue;
|
||||
int minimum_cmd_size;
|
||||
int error_inject;
|
||||
int ordered_tag_count;
|
||||
@ -903,6 +904,8 @@ static timeout_t damediapoll;
|
||||
#define DA_DEFAULT_SEND_ORDERED 1
|
||||
#endif
|
||||
|
||||
#define DA_SIO (softc->sort_io_queue >= 0 ? \
|
||||
softc->sort_io_queue : cam_sort_io_queues)
|
||||
|
||||
static int da_poll_period = DA_DEFAULT_POLL_PERIOD;
|
||||
static int da_retry_count = DA_DEFAULT_RETRY;
|
||||
@ -1140,10 +1143,15 @@ dastrategy(struct bio *bp)
|
||||
if (bp->bio_cmd == BIO_DELETE) {
|
||||
if (bp->bio_bcount == 0)
|
||||
biodone(bp);
|
||||
else
|
||||
else if (DA_SIO)
|
||||
bioq_disksort(&softc->delete_queue, bp);
|
||||
} else
|
||||
else
|
||||
bioq_insert_tail(&softc->delete_queue, bp);
|
||||
} else if (DA_SIO) {
|
||||
bioq_disksort(&softc->bio_queue, bp);
|
||||
} else {
|
||||
bioq_insert_tail(&softc->bio_queue, bp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Schedule ourselves for performing the work.
|
||||
@ -1504,6 +1512,9 @@ dasysctlinit(void *context, int pending)
|
||||
OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
|
||||
&softc->minimum_cmd_size, 0, dacmdsizesysctl, "I",
|
||||
"Minimum CDB size");
|
||||
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
|
||||
OID_AUTO, "sort_io_queue", CTLFLAG_RW, &softc->sort_io_queue, 0,
|
||||
"Sort IO queue to try and optimise disk access patterns");
|
||||
|
||||
SYSCTL_ADD_INT(&softc->sysctl_ctx,
|
||||
SYSCTL_CHILDREN(softc->sysctl_tree),
|
||||
@ -1651,6 +1662,7 @@ daregister(struct cam_periph *periph, void *arg)
|
||||
softc->flags |= DA_FLAG_PACK_REMOVABLE;
|
||||
softc->unmap_max_ranges = UNMAP_MAX_RANGES;
|
||||
softc->unmap_max_lba = 1024*1024*2;
|
||||
softc->sort_io_queue = -1;
|
||||
|
||||
periph->softc = softc;
|
||||
|
||||
@ -2133,9 +2145,16 @@ cmd6workaround(union ccb *ccb)
|
||||
dadeletemethodset(softc, DA_DELETE_DISABLE);
|
||||
} else
|
||||
dadeletemethodset(softc, DA_DELETE_DISABLE);
|
||||
while ((bp = bioq_takefirst(&softc->delete_run_queue))
|
||||
!= NULL)
|
||||
bioq_disksort(&softc->delete_queue, bp);
|
||||
|
||||
if (DA_SIO) {
|
||||
while ((bp = bioq_takefirst(&softc->delete_run_queue))
|
||||
!= NULL)
|
||||
bioq_disksort(&softc->delete_queue, bp);
|
||||
} else {
|
||||
while ((bp = bioq_takefirst(&softc->delete_run_queue))
|
||||
!= NULL)
|
||||
bioq_insert_tail(&softc->delete_queue, bp);
|
||||
}
|
||||
bioq_insert_tail(&softc->delete_queue,
|
||||
(struct bio *)ccb->ccb_h.ccb_bp);
|
||||
ccb->ccb_h.ccb_bp = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user