changeset 10243:051184299af5

6833062 Assertion panic on X2100 system with summit HBA while running SAN fctape test
author Nikko He <Li.He@Sun.COM>
date Mon, 03 Aug 2009 10:45:08 +0800
parents c40d075fbca6
children b9aac0ba7895
files usr/src/uts/common/io/scsi/impl/scsi_resource.c
diffstat 1 files changed, 33 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/scsi/impl/scsi_resource.c	Sat Aug 01 15:09:50 2009 -0600
+++ b/usr/src/uts/common/io/scsi/impl/scsi_resource.c	Mon Aug 03 10:45:08 2009 +0800
@@ -285,6 +285,37 @@
 			kf = KM_SLEEP;
 		else
 			kf = KM_NOSLEEP;
+		/*
+		 * By using kmem_cache_alloc(), the layout of the
+		 * scsi_pkt, scsi_pkt_cache_wrapper, hba private data,
+		 * cdb, tgt driver private data, and status block is
+		 * as below.
+		 *
+		 * This is a piece of contiguous memory starting from
+		 * the first structure field scsi_pkt in the struct
+		 * scsi_pkt_cache_wrapper, followed by the hba private
+		 * data, pkt_cdbp, the tgt driver private data and
+		 * pkt_scbp.
+		 *
+		 * |----------------------------|--------------------->
+		 * |	struct scsi_pkt		|	struct
+		 * |	......			|scsi_pkt_cache_wrapper
+		 * |	pcw_flags		|
+		 * |----------------------------|<---------------------
+		 * |	hba private data	|tranp->tran_hba_len
+		 * |----------------------------|
+		 * |	pkt_cdbp		|DEFAULT_CDBLEN
+		 * |----------------------------|
+		 * |	tgt private data	|DEFAULT_PRIVLEN
+		 * |----------------------------|
+		 * |	pkt_scbp		|DEFAULT_SCBLEN
+		 * |----------------------------|
+		 *
+		 * If the actual data length of the cdb, or the tgt
+		 * driver private data, or the status block is bigger
+		 * than the default data length, kmem_alloc() will be
+		 * called to get extra space.
+		 */
 		pktw = kmem_cache_alloc(tranp->tran_pkt_cache_ptr,
 		    kf);
 		if (pktw == NULL)
@@ -450,7 +481,7 @@
 		kmem_free(in_pktp->pkt_scbp, statuslen);
 		in_pktp->pkt_scbp = (opaque_t)((char *)in_pktp +
 		    tranp->tran_hba_len + DEFAULT_PRIVLEN +
-		    sizeof (struct scsi_pkt));
+		    sizeof (struct scsi_pkt_cache_wrapper));
 		if ((A_TO_TRAN(ap))->tran_hba_flags & SCSI_HBA_TRAN_CDB)
 			in_pktp->pkt_scbp = (opaque_t)((in_pktp->pkt_scbp) +
 			    DEFAULT_CDBLEN);
@@ -467,7 +498,7 @@
 		kmem_free(in_pktp->pkt_cdbp, cmdlen);
 		in_pktp->pkt_cdbp = (opaque_t)((char *)in_pktp +
 		    tranp->tran_hba_len +
-		    sizeof (struct scsi_pkt));
+		    sizeof (struct scsi_pkt_cache_wrapper));
 		in_pktp->pkt_cdblen = 0;
 	}
 	pktw->pcw_flags &=