6895299 No SAS_phy_stat kstat counters are created after moving cable from one SIM to another
authorSrikanth Suravajhala <srikanth.suravajhala@oracle.com>
Mon, 05 Apr 2010 18:56:56 -0400
changeset 12077 fb344a67eeb9
parent 12076 f531e5ff251f
child 12078 b3cbeb7a9c80
6895299 No SAS_phy_stat kstat counters are created after moving cable from one SIM to another
usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c
usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c
usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c	Mon Apr 05 15:52:44 2010 -0700
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c	Mon Apr 05 18:56:56 2010 -0400
@@ -111,7 +111,7 @@
 static int pmcs_quiesce(dev_info_t *dip);
 static boolean_t pmcs_fabricate_wwid(pmcs_hw_t *);
 
-static void pmcs_create_phy_stats(pmcs_iport_t *);
+static void pmcs_create_all_phy_stats(pmcs_iport_t *);
 int pmcs_update_phy_stats(kstat_t *, int);
 static void pmcs_destroy_phy_stats(pmcs_iport_t *);
 
@@ -374,7 +374,7 @@
 	mutex_exit(&iport->lock);
 
 	/* Create kstats for each of the phys in this port */
-	pmcs_create_phy_stats(iport);
+	pmcs_create_all_phy_stats(iport);
 
 	/*
 	 * Insert this iport handle into our list and set
@@ -3008,15 +3008,78 @@
 	pwp->scratch_locked = 0;
 }
 
-static void
-pmcs_create_phy_stats(pmcs_iport_t *iport)
+/* Called with iport_lock and phy lock held */
+void
+pmcs_create_one_phy_stats(pmcs_iport_t *iport, pmcs_phy_t *phyp)
 {
 	sas_phy_stats_t		*ps;
 	pmcs_hw_t		*pwp;
-	pmcs_phy_t		*phyp;
 	int			ndata;
 	char			ks_name[KSTAT_STRLEN];
 
+	ASSERT(mutex_owned(&iport->lock));
+	pwp = iport->pwp;
+	ASSERT(pwp != NULL);
+	ASSERT(mutex_owned(&phyp->phy_lock));
+
+	if (phyp->phy_stats != NULL) {
+		/*
+		 * Delete existing kstats with name containing
+		 * old iport instance# and allow creation of
+		 * new kstats with new iport instance# in the name.
+		 */
+		kstat_delete(phyp->phy_stats);
+	}
+
+	ndata = (sizeof (sas_phy_stats_t)/sizeof (kstat_named_t));
+
+	(void) snprintf(ks_name, sizeof (ks_name),
+	    "%s.%llx.%d.%d", ddi_driver_name(iport->dip),
+	    (longlong_t)pwp->sas_wwns[0],
+	    ddi_get_instance(iport->dip), phyp->phynum);
+
+	phyp->phy_stats = kstat_create("pmcs",
+	    ddi_get_instance(iport->dip), ks_name, KSTAT_SAS_PHY_CLASS,
+	    KSTAT_TYPE_NAMED, ndata, 0);
+
+	if (phyp->phy_stats == NULL) {
+		pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL,
+		    "%s: Failed to create %s kstats for PHY(0x%p) at %s",
+		    __func__, ks_name, (void *)phyp, phyp->path);
+	}
+
+	ps = (sas_phy_stats_t *)phyp->phy_stats->ks_data;
+
+	kstat_named_init(&ps->seconds_since_last_reset,
+	    "SecondsSinceLastReset", KSTAT_DATA_ULONGLONG);
+	kstat_named_init(&ps->tx_frames,
+	    "TxFrames", KSTAT_DATA_ULONGLONG);
+	kstat_named_init(&ps->rx_frames,
+	    "RxFrames", KSTAT_DATA_ULONGLONG);
+	kstat_named_init(&ps->tx_words,
+	    "TxWords", KSTAT_DATA_ULONGLONG);
+	kstat_named_init(&ps->rx_words,
+	    "RxWords", KSTAT_DATA_ULONGLONG);
+	kstat_named_init(&ps->invalid_dword_count,
+	    "InvalidDwordCount", KSTAT_DATA_ULONGLONG);
+	kstat_named_init(&ps->running_disparity_error_count,
+	    "RunningDisparityErrorCount", KSTAT_DATA_ULONGLONG);
+	kstat_named_init(&ps->loss_of_dword_sync_count,
+	    "LossofDwordSyncCount", KSTAT_DATA_ULONGLONG);
+	kstat_named_init(&ps->phy_reset_problem_count,
+	    "PhyResetProblemCount", KSTAT_DATA_ULONGLONG);
+
+	phyp->phy_stats->ks_private = phyp;
+	phyp->phy_stats->ks_update = pmcs_update_phy_stats;
+	kstat_install(phyp->phy_stats);
+}
+
+static void
+pmcs_create_all_phy_stats(pmcs_iport_t *iport)
+{
+	pmcs_hw_t		*pwp;
+	pmcs_phy_t		*phyp;
+
 	ASSERT(iport != NULL);
 	pwp = iport->pwp;
 	ASSERT(pwp != NULL);
@@ -3027,58 +3090,9 @@
 	    phyp != NULL;
 	    phyp = list_next(&iport->phys, phyp)) {
 
-		pmcs_lock_phy(phyp);
-
-		if (phyp->phy_stats != NULL) {
-			pmcs_unlock_phy(phyp);
-			/* We've already created this kstat instance */
-			continue;
-		}
-
-		ndata = (sizeof (sas_phy_stats_t)/sizeof (kstat_named_t));
-
-		(void) snprintf(ks_name, sizeof (ks_name),
-		    "%s.%llx.%d.%d", ddi_driver_name(iport->dip),
-		    (longlong_t)pwp->sas_wwns[0],
-		    ddi_get_instance(iport->dip), phyp->phynum);
-
-		phyp->phy_stats = kstat_create("pmcs",
-		    ddi_get_instance(iport->dip), ks_name, KSTAT_SAS_PHY_CLASS,
-		    KSTAT_TYPE_NAMED, ndata, 0);
-
-		if (phyp->phy_stats == NULL) {
-			pmcs_unlock_phy(phyp);
-			pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL,
-			    "%s: Failed to create %s kstats", __func__,
-			    ks_name);
-			continue;
-		}
-
-		ps = (sas_phy_stats_t *)phyp->phy_stats->ks_data;
-
-		kstat_named_init(&ps->seconds_since_last_reset,
-		    "SecondsSinceLastReset", KSTAT_DATA_ULONGLONG);
-		kstat_named_init(&ps->tx_frames,
-		    "TxFrames", KSTAT_DATA_ULONGLONG);
-		kstat_named_init(&ps->rx_frames,
-		    "RxFrames", KSTAT_DATA_ULONGLONG);
-		kstat_named_init(&ps->tx_words,
-		    "TxWords", KSTAT_DATA_ULONGLONG);
-		kstat_named_init(&ps->rx_words,
-		    "RxWords", KSTAT_DATA_ULONGLONG);
-		kstat_named_init(&ps->invalid_dword_count,
-		    "InvalidDwordCount", KSTAT_DATA_ULONGLONG);
-		kstat_named_init(&ps->running_disparity_error_count,
-		    "RunningDisparityErrorCount", KSTAT_DATA_ULONGLONG);
-		kstat_named_init(&ps->loss_of_dword_sync_count,
-		    "LossofDwordSyncCount", KSTAT_DATA_ULONGLONG);
-		kstat_named_init(&ps->phy_reset_problem_count,
-		    "PhyResetProblemCount", KSTAT_DATA_ULONGLONG);
-
-		phyp->phy_stats->ks_private = phyp;
-		phyp->phy_stats->ks_update = pmcs_update_phy_stats;
-		kstat_install(phyp->phy_stats);
-		pmcs_unlock_phy(phyp);
+		mutex_enter(&phyp->phy_lock);
+		pmcs_create_one_phy_stats(iport, phyp);
+		mutex_exit(&phyp->phy_lock);
 	}
 
 	mutex_exit(&iport->lock);
@@ -3141,12 +3155,17 @@
 		return;
 	}
 
-	pmcs_lock_phy(phyp);
-	if (phyp->phy_stats != NULL) {
-		kstat_delete(phyp->phy_stats);
-		phyp->phy_stats = NULL;
+	for (phyp = list_head(&iport->phys);
+	    phyp != NULL;
+	    phyp = list_next(&iport->phys, phyp)) {
+
+		mutex_enter(&phyp->phy_lock);
+		if (phyp->phy_stats != NULL) {
+			kstat_delete(phyp->phy_stats);
+			phyp->phy_stats = NULL;
+		}
+		mutex_exit(&phyp->phy_lock);
 	}
-	pmcs_unlock_phy(phyp);
 
 	mutex_exit(&iport->lock);
 }
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c	Mon Apr 05 15:52:44 2010 -0700
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c	Mon Apr 05 18:56:56 2010 -0400
@@ -7897,6 +7897,9 @@
 	list_insert_tail(&iport->phys, phyp);
 	pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS,
 	    &iport->nphy);
+	mutex_enter(&phyp->phy_lock);
+	pmcs_create_one_phy_stats(iport, phyp);
+	mutex_exit(&phyp->phy_lock);
 	mutex_enter(&iport->refcnt_lock);
 	iport->refcnt++;
 	mutex_exit(&iport->refcnt_lock);
@@ -7920,6 +7923,10 @@
 		    pptr = next_pptr) {
 			next_pptr = list_next(&iport->phys, pptr);
 			mutex_enter(&pptr->phy_lock);
+			if (pptr->phy_stats != NULL) {
+				kstat_delete(pptr->phy_stats);
+				pptr->phy_stats = NULL;
+			}
 			pptr->iport = NULL;
 			pmcs_update_phy_pm_props(pptr, pptr->att_port_pm_tmp,
 			    pptr->tgt_port_pm_tmp, B_FALSE);
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h	Mon Apr 05 15:52:44 2010 -0700
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h	Mon Apr 05 18:56:56 2010 -0400
@@ -289,7 +289,7 @@
  */
 void pmcs_check_iomb_status(pmcs_hw_t *pwp, uint32_t *iomb);
 void pmcs_clear_xp(pmcs_hw_t *, pmcs_xscsi_t *);
-
+void pmcs_create_one_phy_stats(pmcs_iport_t *, pmcs_phy_t *);
 int pmcs_run_sata_cmd(pmcs_hw_t *, pmcs_phy_t *, fis_t, uint32_t,
     uint32_t, uint32_t);
 int pmcs_sata_identify(pmcs_hw_t *, pmcs_phy_t *);