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
This commit is contained in:
parent
9fe9ba5bef
commit
90edda31ba
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=249941
@ -1155,7 +1155,11 @@ 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;
|
||||
/* 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,
|
||||
|
@ -1429,6 +1429,30 @@ struct scsi_diag_page {
|
||||
uint8_t params[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -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 @@ dastart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
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 ccb *done_ccb)
|
||||
}
|
||||
|
||||
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 ccb *done_ccb)
|
||||
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 ccb *done_ccb)
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user