6928278 scsav3: scsi_hba_tgtmap_set_flush
authorReed <Reed.Liu@Sun.COM>
Thu, 25 Mar 2010 20:25:11 -0600
changeset 12000 19ca97e58197
parent 11999 0f7f7e594e5a
child 12001 ae8584566c0b
6928278 scsav3: scsi_hba_tgtmap_set_flush
usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c
usr/src/uts/common/io/scsi/impl/scsi_hba.c
usr/src/uts/common/os/damap.c
usr/src/uts/common/sys/damap.h
usr/src/uts/common/sys/scsi/impl/transport.h
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c	Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c	Thu Mar 25 20:25:11 2010 -0600
@@ -53,6 +53,7 @@
 static void pmcs_clear_phys(pmcs_hw_t *, pmcs_phy_t *);
 static int pmcs_configure_new_devices(pmcs_hw_t *, pmcs_phy_t *);
 static void pmcs_begin_observations(pmcs_hw_t *);
+static void pmcs_flush_observations(pmcs_hw_t *);
 static boolean_t pmcs_report_observations(pmcs_hw_t *);
 static boolean_t pmcs_report_iport_observations(pmcs_hw_t *, pmcs_iport_t *,
     pmcs_phy_t *);
@@ -2371,7 +2372,6 @@
 {
 	pmcs_phy_t		*pptr;
 	pmcs_phy_t		*root_phy;
-	int			phymap_active;
 
 	DTRACE_PROBE2(pmcs__discover__entry, ulong_t, pwp->work_flags,
 	    boolean_t, pwp->config_changed);
@@ -2391,7 +2391,6 @@
 		return;
 	}
 
-	phymap_active = pwp->phymap_active;
 	mutex_exit(&pwp->lock);
 
 	/*
@@ -2406,14 +2405,6 @@
 		SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER);
 		return;
 	}
-	if (pwp->num_iports != phymap_active) {
-		rw_exit(&pwp->iports_lock);
-		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
-		    "%s: phymaps or iport maps not stable; retry discovery",
-		    __func__);
-		SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER);
-		return;
-	}
 	rw_exit(&pwp->iports_lock);
 
 	mutex_enter(&pwp->config_lock);
@@ -2580,6 +2571,7 @@
 restart:
 	/* Clean up and restart discovery */
 	pmcs_release_scratch(pwp);
+	pmcs_flush_observations(pwp);
 	mutex_enter(&pwp->config_lock);
 	pwp->configuring = 0;
 	RESTART_DISCOVERY_LOCKED(pwp);
@@ -2664,6 +2656,41 @@
 }
 
 /*
+ * Tell SCSA to flush the observations we've already sent (if any), as they
+ * are no longer valid.
+ */
+static void
+pmcs_flush_observations(pmcs_hw_t *pwp)
+{
+	pmcs_iport_t		*iport;
+	scsi_hba_tgtmap_t	*tgtmap;
+
+	rw_enter(&pwp->iports_lock, RW_READER);
+	for (iport = list_head(&pwp->iports); iport != NULL;
+	    iport = list_next(&pwp->iports, iport)) {
+		/*
+		 * Skip this iport if it has no PHYs up.
+		 */
+		if (!sas_phymap_uahasphys(pwp->hss_phymap, iport->ua)) {
+			continue;
+		}
+
+		tgtmap = iport->iss_tgtmap;
+		ASSERT(tgtmap);
+		if (scsi_hba_tgtmap_set_flush(tgtmap) != DDI_SUCCESS) {
+			pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL,
+			    "%s: Failed set_flush on tgtmap 0x%p", __func__,
+			    (void *)tgtmap);
+		} else {
+			pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL,
+			    "%s: set flush on tgtmap 0x%p", __func__,
+			    (void *)tgtmap);
+		}
+	}
+	rw_exit(&pwp->iports_lock);
+}
+
+/*
  * Report current observations to SCSA.
  */
 static boolean_t
--- a/usr/src/uts/common/io/scsi/impl/scsi_hba.c	Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/io/scsi/impl/scsi_hba.c	Thu Mar 25 20:25:11 2010 -0600
@@ -5162,7 +5162,7 @@
 		 * kernels.
 		 */
 		SCSI_HBA_LOG((_LOG(1), NULL, self,
-		    "no node_name for device @%s:\n         compatible: %s",
+		    "no node_name for device @%s:\n	 compatible: %s",
 		    addr, *compat));
 		goto out;
 	}
@@ -8413,52 +8413,71 @@
 	return (empty);
 }
 
-int
-scsi_hba_tgtmap_set_begin(scsi_hba_tgtmap_t *handle)
+static int
+scsi_tgtmap_begin_or_flush(scsi_hba_tgtmap_t *handle, boolean_t do_begin)
 {
 	impl_scsi_tgtmap_t	*tgtmap = (impl_scsi_tgtmap_t *)handle;
 	dev_info_t		*self = tgtmap->tgtmap_tran->tran_iport_dip;
 	char			*context;
-	int			rv = DDI_SUCCESS;
+	int			rv = DAM_SUCCESS;
 	int			i;
 
 	for (i = 0; i < SCSI_TGT_NTYPES; i++) {
-		if (tgtmap->tgtmap_dam[i] == NULL)
+		if (tgtmap->tgtmap_dam[i] == NULL) {
 			continue;
+		}
 
 		context = damap_name(tgtmap->tgtmap_dam[i]);
-
-		if (i == SCSI_TGT_SCSI_DEVICE) {
-			/*
-			 * In scsi_device context, so we have the 'context'
-			 * string, diagnose the case where the tgtmap caller
-			 * is failing to make forward progress, i.e. the caller
-			 * is never completing an observation, and calling
-			 * scsi_hbg_tgtmap_set_end. If this occurs, the solaris
-			 * target/lun state may be out of sync with hardware.
-			 */
-			if (tgtmap->tgtmap_reports++ >=
-			    scsi_hba_tgtmap_reports_max) {
-				tgtmap->tgtmap_noisy++;
-				if (tgtmap->tgtmap_noisy == 1)
-					SCSI_HBA_LOG((_LOG(WARN), self, NULL,
-					    "%s: failing to complete a tgtmap "
-					    "observation", context));
+		if (do_begin == B_TRUE) {
+			if (i == SCSI_TGT_SCSI_DEVICE) {
+				/*
+				 * In scsi_device context, so we have the
+				 * 'context' string, diagnose the case where
+				 * the tgtmap caller is failing to make
+				 * forward progress, i.e. the caller is never
+				 * completing an observation, and calling
+				 * scsi_hbg_tgtmap_set_end. If this occurs,
+				 * the solaris target/lun state may be out
+				 * of sync with hardware.
+				 */
+				if (tgtmap->tgtmap_reports++ >=
+				    scsi_hba_tgtmap_reports_max) {
+					tgtmap->tgtmap_noisy++;
+					if (tgtmap->tgtmap_noisy == 1) {
+						SCSI_HBA_LOG((_LOG(WARN), self,
+						    NULL, "%s: failing a tgtmap"
+						    " observation", context));
+					}
+				}
 			}
-		}
-
-		if (damap_addrset_begin(
-		    tgtmap->tgtmap_dam[i]) != DAM_SUCCESS) {
+
+			rv = damap_addrset_begin(tgtmap->tgtmap_dam[i]);
+		} else {
+			rv = damap_addrset_flush(tgtmap->tgtmap_dam[i]);
+		}
+
+		if (rv != DAM_SUCCESS) {
 			SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s FAIL", context));
-			rv = DDI_FAILURE;
-			continue;
-		}
-
-		SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context));
-	}
-	return (rv);
-}
-
+		} else {
+			SCSI_HBA_LOG((_LOGTGT, self, NULL, "%s", context));
+		}
+	}
+
+	return ((rv == DAM_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
+}
+
+
+int
+scsi_hba_tgtmap_set_begin(scsi_hba_tgtmap_t *handle)
+{
+	return (scsi_tgtmap_begin_or_flush(handle, B_TRUE));
+}
+
+int
+scsi_hba_tgtmap_set_flush(scsi_hba_tgtmap_t *handle)
+{
+	return (scsi_tgtmap_begin_or_flush(handle, B_FALSE));
+}
 
 int
 scsi_hba_tgtmap_set_add(scsi_hba_tgtmap_t *handle,
--- a/usr/src/uts/common/os/damap.c	Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/os/damap.c	Thu Mar 25 20:25:11 2010 -0600
@@ -434,6 +434,46 @@
 	return (DAM_SUCCESS);
 }
 
+static int
+damap_addrset_flush_locked(damap_t *damapp)
+{
+	dam_t   *mapp = (dam_t *)damapp;
+	int	idx;
+
+	ASSERT(mapp);
+	ASSERT(mutex_owned(&mapp->dam_lock));
+	if (mapp->dam_rptmode != DAMAP_REPORT_FULLSET) {
+		return (DAM_EINVAL);
+	}
+
+	DTRACE_PROBE2(damap__addrset__flush__locked__enter, char *,
+	    mapp->dam_name, dam_t *, mapp);
+	if (mapp->dam_flags & DAM_SETADD) {
+		DTRACE_PROBE2(damap__addrset__flush__locked__reset, char *,
+		    mapp->dam_name, dam_t *, mapp);
+
+		/*
+		 * cancel stabilization timeout
+		 */
+		dam_sched_tmo(mapp, 0, NULL);
+		DAM_INCR_STAT(mapp, dam_jitter);
+
+		/*
+		 * clear pending reports
+		 */
+		for (idx = 1; idx < mapp->dam_high; idx++) {
+			if (DAM_IN_REPORT(mapp, idx)) {
+				dam_addr_report_release(mapp, idx);
+			}
+		}
+
+		bitset_zero(&mapp->dam_report_set);
+		mapp->dam_flags &= ~DAM_SETADD;
+	}
+
+	return (DAM_SUCCESS);
+}
+
 /*
  * Initiate full-set report
  *
@@ -445,40 +485,58 @@
 int
 damap_addrset_begin(damap_t *damapp)
 {
-	dam_t *mapp = (dam_t *)damapp;
-	int i;
+	dam_t	*mapp = (dam_t *)damapp;
+	int	rv;
 
-	if (!mapp || (mapp->dam_rptmode != DAMAP_REPORT_FULLSET))
+	if (mapp == NULL) {
 		return (DAM_EINVAL);
+	}
 
 	DTRACE_PROBE2(damap__addrset__begin, char *, mapp->dam_name, dam_t *,
 	    mapp);
+
 	mutex_enter(&mapp->dam_lock);
 	if (dam_map_alloc(mapp) != DAM_SUCCESS) {
 		mutex_exit(&mapp->dam_lock);
+
 		return (DAM_MAPFULL);
 	}
-	if (mapp->dam_flags & DAM_SETADD) {
-		DTRACE_PROBE2(damap__addrset__begin__reset, char *,
-		    mapp->dam_name, dam_t *, mapp);
-		/*
-		 * cancel stabilization timeout
-		 */
-		dam_sched_tmo(mapp, 0, NULL);
-		DAM_INCR_STAT(mapp, dam_jitter);
+
+	rv = damap_addrset_flush_locked(damapp);
+	if (rv == DAM_SUCCESS) {
+		mapp->dam_flags |= DAM_SETADD;
+	}
+	mutex_exit(&mapp->dam_lock);
+
+	return (rv);
+}
 
-		/*
-		 * clear pending reports
-		 */
-		for (i = 1; i < mapp->dam_high; i++) {
-			if (DAM_IN_REPORT(mapp, i))
-				dam_addr_report_release(mapp, i);
-		}
+/*
+ * Cancel full-set report
+ *
+ * damapp:      address map
+ *
+ * Returns:     DAM_SUCCESS
+ *	      DAM_EINVAL      Invalid argument(s)
+ */
+int
+damap_addrset_flush(damap_t *damapp)
+{
+	int	rv;
+	dam_t	*mapp = (dam_t *)damapp;
+
+	if (mapp == NULL) {
+		return (DAM_EINVAL);
 	}
-	bitset_zero(&mapp->dam_report_set);
-	mapp->dam_flags |= DAM_SETADD;
+
+	DTRACE_PROBE2(damap__addrset__flush, char *, mapp->dam_name,
+	    dam_t *, mapp);
+
+	mutex_enter(&mapp->dam_lock);
+	rv = damap_addrset_flush_locked(damapp);
 	mutex_exit(&mapp->dam_lock);
-	return (DAM_SUCCESS);
+
+	return (rv);
 }
 
 /*
--- a/usr/src/uts/common/sys/damap.h	Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/sys/damap.h	Thu Mar 25 20:25:11 2010 -0600
@@ -152,6 +152,7 @@
 int		damap_addrset_add(damap_t *, char *, damap_id_t *,
 		    nvlist_t *, void *);
 int		damap_addrset_end(damap_t *, int);
+int		damap_addrset_flush(damap_t *);
 int		damap_addrset_reset(damap_t *, int);
 damap_id_t	damap_id_next(damap_t *, damap_id_list_t, damap_id_t);
 char		*damap_id2addr(damap_t *, damap_id_t);
--- a/usr/src/uts/common/sys/scsi/impl/transport.h	Fri Mar 26 09:22:57 2010 +0800
+++ b/usr/src/uts/common/sys/scsi/impl/transport.h	Thu Mar 25 20:25:11 2010 -0600
@@ -643,6 +643,8 @@
 				scsi_hba_tgtmap_t	*tgtmap,
 				uint_t			flags);
 
+int	scsi_hba_tgtmap_set_flush(scsi_hba_tgtmap_t	*tgtmap);
+
 int	scsi_hba_tgtmap_tgt_add(
 				scsi_hba_tgtmap_t	*tgtmap,
 				scsi_tgtmap_tgt_type_t	tgt_type,