Date: Sat, 21 Aug 2021 13:58:10 GMT From: Alexander Motin <mav@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 84d5b6bd68ce - main - cam(4): Fix quick unplug/replug for SCSI. Message-ID: <202108211358.17LDwA00086258@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by mav: URL: https://cgit.FreeBSD.org/src/commit/?id=84d5b6bd68ce6496592adb8fdcd8cf0c246ed935 commit 84d5b6bd68ce6496592adb8fdcd8cf0c246ed935 Author: Alexander Motin <mav@FreeBSD.org> AuthorDate: 2021-08-21 13:31:41 +0000 Commit: Alexander Motin <mav@FreeBSD.org> CommitDate: 2021-08-21 13:58:05 +0000 cam(4): Fix quick unplug/replug for SCSI. If some device is plugged back in after unplug before the probe periph destroyed, it will just restart the probe process. But I've found that PROBE_INQUIRY_CKSUM flag not cleared between the iterations may cause AC_FOUND_DEVICE not reported on the second iteration, and because of AC_LOST_DEVICE reported during the first iteration, the device end up configured, but without any periphs attached. We've found that enabled serial console and 102-disk JBOD cause enough probe delays to easily trigger the issue for half of the disks. This change fixes it reliably on my tests. MFC after: 2 weeks Sponsored by: iXsystems, Inc. --- sys/cam/scsi/scsi_xpt.c | 61 ++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c index 46cc4c1699f1..c4c43ee87101 100644 --- a/sys/cam/scsi/scsi_xpt.c +++ b/sys/cam/scsi/scsi_xpt.c @@ -178,7 +178,6 @@ do { \ typedef enum { PROBE_INQUIRY_CKSUM = 0x01, - PROBE_SERIAL_CKSUM = 0x02, PROBE_NO_ANNOUNCE = 0x04, PROBE_EXTLUN = 0x08 } probe_flags; @@ -775,8 +774,6 @@ again: } case PROBE_INQUIRY: case PROBE_FULL_INQUIRY: - case PROBE_INQUIRY_BASIC_DV1: - case PROBE_INQUIRY_BASIC_DV2: { u_int inquiry_len; struct scsi_inquiry_data *inq_buf; @@ -791,19 +788,19 @@ again: * serial number check finish, we attempt to figure out * whether we still have the same device. */ - if (((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) - && ((softc->flags & PROBE_INQUIRY_CKSUM) == 0)) { + if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { + softc->flags &= ~PROBE_INQUIRY_CKSUM; + } else if ((softc->flags & PROBE_INQUIRY_CKSUM) == 0) { MD5Init(&softc->context); MD5Update(&softc->context, (unsigned char *)inq_buf, sizeof(struct scsi_inquiry_data)); - softc->flags |= PROBE_INQUIRY_CKSUM; if (periph->path->device->serial_num_len > 0) { MD5Update(&softc->context, periph->path->device->serial_num, periph->path->device->serial_num_len); - softc->flags |= PROBE_SERIAL_CKSUM; } MD5Final(softc->digest, &softc->context); + softc->flags |= PROBE_INQUIRY_CKSUM; } if (softc->action == PROBE_INQUIRY) @@ -819,22 +816,6 @@ again: */ inquiry_len = roundup2(inquiry_len, 2); - if (softc->action == PROBE_INQUIRY_BASIC_DV1 - || softc->action == PROBE_INQUIRY_BASIC_DV2) { - inq_buf = malloc(inquiry_len, M_CAMXPT, M_NOWAIT); - } - if (inq_buf == NULL) { - xpt_print(periph->path, "malloc failure- skipping Basic" - "Domain Validation\n"); - PROBE_SET_ACTION(softc, PROBE_DV_EXIT); - scsi_test_unit_ready(csio, - /*retries*/4, - probedone, - MSG_SIMPLE_Q_TAG, - SSD_FULL_SIZE, - /*timeout*/60000); - break; - } scsi_inquiry(csio, /*retries*/4, probedone, @@ -1019,6 +1000,40 @@ done: } goto done; } + case PROBE_INQUIRY_BASIC_DV1: + case PROBE_INQUIRY_BASIC_DV2: + { + u_int inquiry_len; + struct scsi_inquiry_data *inq_buf; + + inq_buf = &periph->path->device->inq_data; + inquiry_len = roundup2(SID_ADDITIONAL_LENGTH(inq_buf), 2); + inq_buf = malloc(inquiry_len, M_CAMXPT, M_NOWAIT); + if (inq_buf == NULL) { + xpt_print(periph->path, "malloc failure- skipping Basic" + "Domain Validation\n"); + PROBE_SET_ACTION(softc, PROBE_DV_EXIT); + scsi_test_unit_ready(csio, + /*retries*/4, + probedone, + MSG_SIMPLE_Q_TAG, + SSD_FULL_SIZE, + /*timeout*/60000); + break; + } + + scsi_inquiry(csio, + /*retries*/4, + probedone, + MSG_SIMPLE_Q_TAG, + (u_int8_t *)inq_buf, + inquiry_len, + /*evpd*/FALSE, + /*page_code*/0, + SSD_MIN_SIZE, + /*timeout*/60 * 1000); + break; + } default: panic("probestart: invalid action state 0x%x\n", softc->action); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108211358.17LDwA00086258>