summaryrefslogtreecommitdiffstats
path: root/sys/cam/scsi
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-04-30 17:38:26 +0000
committermav <mav@FreeBSD.org>2014-04-30 17:38:26 +0000
commit6429f5f6361b358fde4f2643463a38637e700f1b (patch)
tree2ef9cc10d41bf59907e664fbcd233c39679fe929 /sys/cam/scsi
parent76ae4734f77543830b594a02665f102173732808 (diff)
downloadFreeBSD-src-6429f5f6361b358fde4f2643463a38637e700f1b.zip
FreeBSD-src-6429f5f6361b358fde4f2643463a38637e700f1b.tar.gz
Do not reread SCSI disk VPD pages on every device open.
Instead of rereading VPD pages on every device open, do it only on initial device probe, and in cases when device reported via UNIT ATTENTIONs that something has changed. Capacity is still rereaded on every open because it is more critical for operation and more probable to change in run time. On my tests with Intel 530 SSDs on mps(4) HBA this change reduces time GEOM needs to retaste the device (that includes few open/close cycles) from ~150ms to ~30ms. MFC after: 2 weeks Sponsored by: iXsystems, Inc.
Diffstat (limited to 'sys/cam/scsi')
-rw-r--r--sys/cam/scsi/scsi_da.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index 2faa8dd..0015231 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -90,7 +90,8 @@ typedef enum {
DA_FLAG_SCTX_INIT = 0x200,
DA_FLAG_CAN_RC16 = 0x400,
DA_FLAG_PROBED = 0x800,
- DA_FLAG_DIRTY = 0x1000
+ DA_FLAG_DIRTY = 0x1000,
+ DA_FLAG_ANNOUNCED = 0x2000
} da_flags;
typedef enum {
@@ -1658,10 +1659,18 @@ daasync(void *callback_arg, u_int32_t code,
&error_code, &sense_key, &asc, &ascq)) {
if (asc == 0x2A && ascq == 0x09) {
xpt_print(ccb->ccb_h.path,
- "capacity data has changed\n");
+ "Capacity data has changed\n");
+ softc->flags &= ~DA_FLAG_PROBED;
dareprobe(periph);
- } else if (asc == 0x28 && ascq == 0x00)
+ } else if (asc == 0x28 && ascq == 0x00) {
+ softc->flags &= ~DA_FLAG_PROBED;
disk_media_changed(softc->disk, M_NOWAIT);
+ } else if (asc == 0x3F && ascq == 0x03) {
+ xpt_print(ccb->ccb_h.path,
+ "INQUIRY data has changed\n");
+ softc->flags &= ~DA_FLAG_PROBED;
+ dareprobe(periph);
+ }
}
cam_periph_async(periph, code, path, arg);
break;
@@ -1891,7 +1900,7 @@ daprobedone(struct cam_periph *periph, union ccb *ccb)
dadeletemethodchoose(softc, DA_DELETE_NONE);
- if (bootverbose && (softc->flags & DA_FLAG_PROBED) == 0) {
+ if (bootverbose && (softc->flags & DA_FLAG_ANNOUNCED) == 0) {
char buf[80];
int i, sep;
@@ -1932,10 +1941,11 @@ daprobedone(struct cam_periph *periph, union ccb *ccb)
*/
xpt_release_ccb(ccb);
softc->state = DA_STATE_NORMAL;
+ softc->flags |= DA_FLAG_PROBED;
daschedule(periph);
wakeup(&softc->disk->d_mediasize);
- if ((softc->flags & DA_FLAG_PROBED) == 0) {
- softc->flags |= DA_FLAG_PROBED;
+ if ((softc->flags & DA_FLAG_ANNOUNCED) == 0) {
+ softc->flags |= DA_FLAG_ANNOUNCED;
cam_periph_unhold(periph);
} else
cam_periph_release_locked(periph);
@@ -3190,7 +3200,8 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
}
}
free(csio->data_ptr, M_SCSIDA);
- if (announce_buf[0] != '\0' && ((softc->flags & DA_FLAG_PROBED) == 0)) {
+ if (announce_buf[0] != '\0' &&
+ ((softc->flags & DA_FLAG_ANNOUNCED) == 0)) {
/*
* Create our sysctl variables, now that we know
* we have successfully attached.
@@ -3208,6 +3219,12 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
}
}
+ /* We already probed the device. */
+ if (softc->flags & DA_FLAG_PROBED) {
+ daprobedone(periph, done_ccb);
+ return;
+ }
+
/* Ensure re-probe doesn't see old delete. */
softc->delete_available = 0;
if (lbp && (softc->quirks & DA_Q_NO_UNMAP) == 0) {
@@ -3546,13 +3563,21 @@ daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
*/
else if (sense_key == SSD_KEY_UNIT_ATTENTION &&
asc == 0x2A && ascq == 0x09) {
- xpt_print(periph->path, "capacity data has changed\n");
+ xpt_print(periph->path, "Capacity data has changed\n");
+ softc->flags &= ~DA_FLAG_PROBED;
dareprobe(periph);
sense_flags |= SF_NO_PRINT;
} else if (sense_key == SSD_KEY_UNIT_ATTENTION &&
- asc == 0x28 && ascq == 0x00)
+ asc == 0x28 && ascq == 0x00) {
+ softc->flags &= ~DA_FLAG_PROBED;
disk_media_changed(softc->disk, M_NOWAIT);
- else if (sense_key == SSD_KEY_NOT_READY &&
+ } else if (sense_key == SSD_KEY_UNIT_ATTENTION &&
+ asc == 0x3F && ascq == 0x03) {
+ xpt_print(periph->path, "INQUIRY data has changed\n");
+ softc->flags &= ~DA_FLAG_PROBED;
+ dareprobe(periph);
+ sense_flags |= SF_NO_PRINT;
+ } else if (sense_key == SSD_KEY_NOT_READY &&
asc == 0x3a && (softc->flags & DA_FLAG_PACK_INVALID) == 0) {
softc->flags |= DA_FLAG_PACK_INVALID;
disk_media_gone(softc->disk, M_NOWAIT);
OpenPOWER on IntegriCloud