git: 84d5b6bd68ce - main - cam(4): Fix quick unplug/replug for SCSI.

Alexander Motin mav at FreeBSD.org
Sat Aug 21 13:58:11 UTC 2021


The branch main has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=84d5b6bd68ce6496592adb8fdcd8cf0c246ed935

commit 84d5b6bd68ce6496592adb8fdcd8cf0c246ed935
Author:     Alexander Motin <mav at FreeBSD.org>
AuthorDate: 2021-08-21 13:31:41 +0000
Commit:     Alexander Motin <mav at 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);
 	}


More information about the dev-commits-src-all mailing list