svn commit: r249941 - in head/sys/cam: ata scsi
Steven Hartland
smh at FreeBSD.org
Fri Apr 26 16:31:04 UTC 2013
Author: smh
Date: Fri Apr 26 16:31:03 2013
New Revision: 249941
URL: http://svnweb.freebsd.org/changeset/base/249941
Log:
Added automatic detection of non-rotating media which disables the
use of BIO queue sorting, hence optimising performance for devices
such as SSD's
Reviewed by: scottl
Approved by: pjd (mentor)
MFC after: 2 weeks
Modified:
head/sys/cam/ata/ata_da.c
head/sys/cam/scsi/scsi_all.h
head/sys/cam/scsi/scsi_da.c
Modified: head/sys/cam/ata/ata_da.c
==============================================================================
--- head/sys/cam/ata/ata_da.c Fri Apr 26 16:22:54 2013 (r249940)
+++ head/sys/cam/ata/ata_da.c Fri Apr 26 16:31:03 2013 (r249941)
@@ -1155,7 +1155,11 @@ adaregister(struct cam_periph *periph, v
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;
+ /* Disable queue sorting for non-rotatational media by default */
+ if (cgd->ident_data.media_rotation_rate == 1)
+ softc->sort_io_queue = 0;
+ else
+ softc->sort_io_queue = -1;
adagetparams(periph, cgd);
softc->disk = disk_alloc();
softc->disk->d_devstat = devstat_new_entry(periph->periph_name,
Modified: head/sys/cam/scsi/scsi_all.h
==============================================================================
--- head/sys/cam/scsi/scsi_all.h Fri Apr 26 16:22:54 2013 (r249940)
+++ head/sys/cam/scsi/scsi_all.h Fri Apr 26 16:31:03 2013 (r249941)
@@ -1430,6 +1430,30 @@ struct scsi_diag_page {
};
/*
+ * Block Device Characteristics VPD Page based on
+ * T10/1799-D Revision 31
+ */
+struct scsi_vpd_block_characteristics
+{
+ u_int8_t device;
+ u_int8_t page_code;
+#define SVPD_BDC 0xB1
+ u_int8_t page_length[2];
+ u_int8_t medium_rotation_rate[2];
+#define SVPD_BDC_RATE_NOT_REPORTED 0x00
+#define SVPD_BDC_RATE_NONE_ROTATING 0x01
+ u_int8_t reserved1;
+ u_int8_t nominal_form_factor;
+#define SVPD_BDC_FORM_NOT_REPORTED 0x00
+#define SVPD_BDC_FORM_5_25INCH 0x01
+#define SVPD_BDC_FORM_3_5INCH 0x02
+#define SVPD_BDC_FORM_2_5INCH 0x03
+#define SVPD_BDC_FORM_1_5INCH 0x04
+#define SVPD_BDC_FORM_LESSTHAN_1_5INCH 0x05
+ u_int8_t reserved2[56];
+};
+
+/*
* Logical Block Provisioning VPD Page based on
* T10/1799-D Revision 31
*/
Modified: head/sys/cam/scsi/scsi_da.c
==============================================================================
--- head/sys/cam/scsi/scsi_da.c Fri Apr 26 16:22:54 2013 (r249940)
+++ head/sys/cam/scsi/scsi_da.c Fri Apr 26 16:31:03 2013 (r249941)
@@ -72,6 +72,7 @@ typedef enum {
DA_STATE_PROBE_RC16,
DA_STATE_PROBE_LBP,
DA_STATE_PROBE_BLK_LIMITS,
+ DA_STATE_PROBE_BDC,
DA_STATE_PROBE_ATA,
DA_STATE_NORMAL
} da_state;
@@ -104,12 +105,13 @@ typedef enum {
DA_CCB_PROBE_RC16 = 0x02,
DA_CCB_PROBE_LBP = 0x03,
DA_CCB_PROBE_BLK_LIMITS = 0x04,
- DA_CCB_PROBE_ATA = 0x05,
- DA_CCB_BUFFER_IO = 0x06,
- DA_CCB_WAITING = 0x07,
- DA_CCB_DUMP = 0x08,
- DA_CCB_DELETE = 0x0A,
- DA_CCB_TUR = 0x0B,
+ DA_CCB_PROBE_BDC = 0x05,
+ DA_CCB_PROBE_ATA = 0x06,
+ DA_CCB_BUFFER_IO = 0x07,
+ DA_CCB_WAITING = 0x08,
+ DA_CCB_DUMP = 0x0A,
+ DA_CCB_DELETE = 0x0B,
+ DA_CCB_TUR = 0x0C,
DA_CCB_TYPE_MASK = 0x0F,
DA_CCB_RETRY_UA = 0x10
} da_ccb_state;
@@ -2424,6 +2426,39 @@ out:
xpt_action(start_ccb);
break;
}
+ case DA_STATE_PROBE_BDC:
+ {
+ struct scsi_vpd_block_characteristics *bdc;
+
+ if (!scsi_vpd_supported_page(periph, SVPD_BDC)) {
+ softc->state = DA_STATE_PROBE_ATA;
+ goto skipstate;
+ }
+
+ bdc = (struct scsi_vpd_block_characteristics *)
+ malloc(sizeof(*bdc), M_SCSIDA, M_NOWAIT|M_ZERO);
+
+ if (bdc == NULL) {
+ printf("dastart: Couldn't malloc bdc data\n");
+ /* da_free_periph??? */
+ break;
+ }
+
+ scsi_inquiry(&start_ccb->csio,
+ /*retries*/da_retry_count,
+ /*cbfcnp*/dadone,
+ /*tag_action*/MSG_SIMPLE_Q_TAG,
+ /*inq_buf*/(u_int8_t *)bdc,
+ /*inq_len*/sizeof(*bdc),
+ /*evpd*/TRUE,
+ /*page_code*/SVPD_BDC,
+ /*sense_len*/SSD_MIN_SIZE,
+ /*timeout*/da_default_timeout * 1000);
+ start_ccb->ccb_h.ccb_bp = NULL;
+ start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_BDC;
+ xpt_action(start_ccb);
+ break;
+ }
case DA_STATE_PROBE_ATA:
{
struct ata_params *ata_params;
@@ -2904,7 +2939,7 @@ dadone(struct cam_periph *periph, union
}
xpt_release_ccb(done_ccb);
- softc->state = DA_STATE_PROBE_ATA;
+ softc->state = DA_STATE_PROBE_BDC;
xpt_schedule(periph, priority);
return;
}
@@ -3027,6 +3062,40 @@ dadone(struct cam_periph *periph, union
xpt_schedule(periph, priority);
return;
}
+ case DA_CCB_PROBE_BDC:
+ {
+ struct scsi_vpd_block_characteristics *bdc;
+
+ bdc = (struct scsi_vpd_block_characteristics *)csio->data_ptr;
+
+ if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+ if (scsi_2btoul(bdc->medium_rotation_rate) ==
+ SVPD_BDC_RATE_NONE_ROTATING)
+ softc->sort_io_queue = 0;
+ } else {
+ int error;
+ error = daerror(done_ccb, CAM_RETRY_SELTO,
+ SF_RETRY_UA|SF_NO_PRINT);
+ if (error == ERESTART)
+ return;
+ else if (error != 0) {
+ if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+ /* Don't wedge this device's queue */
+ cam_release_devq(done_ccb->ccb_h.path,
+ /*relsim_flags*/0,
+ /*reduction*/0,
+ /*timeout*/0,
+ /*getcount_only*/0);
+ }
+ }
+ }
+
+ free(bdc, M_SCSIDA);
+ softc->state = DA_STATE_PROBE_ATA;
+ xpt_release_ccb(done_ccb);
+ xpt_schedule(periph, priority);
+ return;
+ }
case DA_CCB_PROBE_ATA:
{
int i;
@@ -3047,6 +3116,12 @@ dadone(struct cam_periph *periph, union
ata_params->max_dsm_blocks *
ATA_DSM_BLK_RANGES);
}
+ /*
+ * Disable queue sorting for non-rotatational media
+ * by default
+ */
+ if (ata_params->media_rotation_rate == 1)
+ softc->sort_io_queue = 0;
} else {
int error;
error = daerror(done_ccb, CAM_RETRY_SELTO,
More information about the svn-src-head
mailing list