svn commit: r308217 - in head/sys/dev: mpr mps

Scott Long scottl at FreeBSD.org
Wed Nov 2 15:13:27 UTC 2016


Author: scottl
Date: Wed Nov  2 15:13:25 2016
New Revision: 308217
URL: https://svnweb.freebsd.org/changeset/base/308217

Log:
  Add a fallback to the device mapper logic.  We've seen systems in the field
  that are apparently misconfigured by the manufacturer and cause the mapping
  logic to fail.  The fallback allows drive numbers to be assigned based on the
  PHY number that they're attached to.  Add sysctls and tunables to overrid
  this new behavior, but they should be considered only necessary for debugging.
  
  Reviewed by:	 imp, smh
  Obtained from:	Netflix
  MFC after:	3 days
  Sponsored by:	D8403

Modified:
  head/sys/dev/mpr/mpr.c
  head/sys/dev/mpr/mpr_sas_lsi.c
  head/sys/dev/mpr/mprvar.h
  head/sys/dev/mps/mps.c
  head/sys/dev/mps/mps_sas_lsi.c
  head/sys/dev/mps/mpsvar.h

Modified: head/sys/dev/mpr/mpr.c
==============================================================================
--- head/sys/dev/mpr/mpr.c	Wed Nov  2 15:11:23 2016	(r308216)
+++ head/sys/dev/mpr/mpr.c	Wed Nov  2 15:13:25 2016	(r308217)
@@ -1376,6 +1376,7 @@ mpr_get_tunables(struct mpr_softc *sc)
 	sc->max_io_pages = MPR_MAXIO_PAGES;
 	sc->enable_ssu = MPR_SSU_ENABLE_SSD_DISABLE_HDD;
 	sc->spinup_wait_time = DEFAULT_SPINUP_WAIT;
+	sc->use_phynum = 1;
 
 	/*
 	 * Grab the global variables.
@@ -1387,6 +1388,7 @@ mpr_get_tunables(struct mpr_softc *sc)
 	TUNABLE_INT_FETCH("hw.mpr.max_io_pages", &sc->max_io_pages);
 	TUNABLE_INT_FETCH("hw.mpr.enable_ssu", &sc->enable_ssu);
 	TUNABLE_INT_FETCH("hw.mpr.spinup_wait_time", &sc->spinup_wait_time);
+	TUNABLE_INT_FETCH("hw.mpr.use_phy_num", &sc->use_phynum);
 
 	/* Grab the unit-instance variables */
 	snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.debug_level",
@@ -1421,6 +1423,10 @@ mpr_get_tunables(struct mpr_softc *sc)
 	snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.spinup_wait_time",
 	    device_get_unit(sc->mpr_dev));
 	TUNABLE_INT_FETCH(tmpstr, &sc->spinup_wait_time);
+
+	snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.use_phy_num",
+	    device_get_unit(sc->mpr_dev));
+	TUNABLE_INT_FETCH(tmpstr, &sc->use_phynum);
 }
 
 static void
@@ -1510,6 +1516,10 @@ mpr_setup_sysctl(struct mpr_softc *sc)
 	    OID_AUTO, "spinup_wait_time", CTLFLAG_RD,
 	    &sc->spinup_wait_time, DEFAULT_SPINUP_WAIT, "seconds to wait for "
 	    "spinup after SATA ID error");
+
+	SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+	    OID_AUTO, "use_phy_num", CTLFLAG_RD, &sc->use_phynum, 0,
+	    "Use the phy number for enumeration");
 }
 
 int

Modified: head/sys/dev/mpr/mpr_sas_lsi.c
==============================================================================
--- head/sys/dev/mpr/mpr_sas_lsi.c	Wed Nov  2 15:11:23 2016	(r308216)
+++ head/sys/dev/mpr/mpr_sas_lsi.c	Wed Nov  2 15:13:25 2016	(r308217)
@@ -757,13 +757,24 @@ mprsas_add_device(struct mpr_softc *sc, 
 		}
 	}
 
-	id = mpr_mapping_get_sas_id(sc, sas_address, handle);
+	/*
+	 * use_phynum:
+	 *  1 - use the PhyNum field as a fallback to the mapping logic
+	 *  0 - never use the PhyNum field
+	 * -1 - only use the PhyNum field
+	 */
+	id = MPR_MAP_BAD_ID;
+	if (sc->use_phynum != -1) 
+		id = mpr_mapping_get_sas_id(sc, sas_address, handle);
 	if (id == MPR_MAP_BAD_ID) {
-		printf("failure at %s:%d/%s()! Could not get ID for device "
-		    "with handle 0x%04x\n", __FILE__, __LINE__, __func__,
-		    handle);
-		error = ENXIO;
-		goto out;
+		if ((sc->use_phynum == 0)
+		 || ((id = config_page.PhyNum) > sassc->maxtargets)) {
+			mpr_dprint(sc, MPR_INFO, "failure at %s:%d/%s()! "
+			    "Could not get ID for device with handle 0x%04x\n",
+			    __FILE__, __LINE__, __func__, handle);
+			error = ENXIO;
+			goto out;
+		}
 	}
 
 	if (mprsas_check_id(sassc, id) != 0) {
@@ -772,9 +783,16 @@ mprsas_add_device(struct mpr_softc *sc, 
 		goto out;
 	}
 
+	targ = &sassc->targets[id];
+	if (targ->handle != 0x0) {
+		mpr_dprint(sc, MPR_MAPPING, "Attempting to reuse target id "
+		    "%d handle 0x%04x\n", id, targ->handle);
+		error = ENXIO;
+		goto out;
+	}
+
 	mpr_dprint(sc, MPR_MAPPING, "SAS Address from SAS device page0 = %jx\n",
 	    sas_address);
-	targ = &sassc->targets[id];
 	targ->devinfo = device_info;
 	targ->devname = le32toh(config_page.DeviceName.High);
 	targ->devname = (targ->devname << 32) | 

Modified: head/sys/dev/mpr/mprvar.h
==============================================================================
--- head/sys/dev/mpr/mprvar.h	Wed Nov  2 15:11:23 2016	(r308216)
+++ head/sys/dev/mpr/mprvar.h	Wed Nov  2 15:13:25 2016	(r308217)
@@ -271,6 +271,7 @@ struct mpr_softc {
 	uint16_t			chain_seg_size;
 	u_int				enable_ssu;
 	int				spinup_wait_time;
+	int				use_phynum;
 	uint64_t			chain_alloc_fail;
 	struct sysctl_ctx_list		sysctl_ctx;
 	struct sysctl_oid		*sysctl_tree;

Modified: head/sys/dev/mps/mps.c
==============================================================================
--- head/sys/dev/mps/mps.c	Wed Nov  2 15:11:23 2016	(r308216)
+++ head/sys/dev/mps/mps.c	Wed Nov  2 15:13:25 2016	(r308217)
@@ -1353,6 +1353,7 @@ mps_get_tunables(struct mps_softc *sc)
 	sc->max_io_pages = MPS_MAXIO_PAGES;
 	sc->enable_ssu = MPS_SSU_ENABLE_SSD_DISABLE_HDD;
 	sc->spinup_wait_time = DEFAULT_SPINUP_WAIT;
+	sc->use_phynum = 1;
 
 	/*
 	 * Grab the global variables.
@@ -1364,6 +1365,7 @@ mps_get_tunables(struct mps_softc *sc)
 	TUNABLE_INT_FETCH("hw.mps.max_io_pages", &sc->max_io_pages);
 	TUNABLE_INT_FETCH("hw.mps.enable_ssu", &sc->enable_ssu);
 	TUNABLE_INT_FETCH("hw.mps.spinup_wait_time", &sc->spinup_wait_time);
+	TUNABLE_INT_FETCH("hw.mps.use_phy_num", &sc->use_phynum);
 
 	/* Grab the unit-instance variables */
 	snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.debug_level",
@@ -1398,6 +1400,10 @@ mps_get_tunables(struct mps_softc *sc)
 	snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.spinup_wait_time",
 	    device_get_unit(sc->mps_dev));
 	TUNABLE_INT_FETCH(tmpstr, &sc->spinup_wait_time);
+
+	snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.use_phy_num",
+	    device_get_unit(sc->mps_dev));
+	TUNABLE_INT_FETCH(tmpstr, &sc->use_phynum);
 }
 
 static void
@@ -1495,6 +1501,10 @@ mps_setup_sysctl(struct mps_softc *sc)
 	SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
 	    OID_AUTO, "encl_table_dump", CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
 	    mps_mapping_encl_dump, "A", "Enclosure Table Dump");
+
+	SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+	    OID_AUTO, "use_phy_num", CTLFLAG_RD, &sc->use_phynum, 0,
+	    "Use the phy number for enumeration");
 }
 
 int

Modified: head/sys/dev/mps/mps_sas_lsi.c
==============================================================================
--- head/sys/dev/mps/mps_sas_lsi.c	Wed Nov  2 15:11:23 2016	(r308216)
+++ head/sys/dev/mps/mps_sas_lsi.c	Wed Nov  2 15:13:25 2016	(r308217)
@@ -669,13 +669,24 @@ mpssas_add_device(struct mps_softc *sc, 
 		}
 	}
 
-	id = mps_mapping_get_sas_id(sc, sas_address, handle);
+	/*
+	 * use_phynum:
+	 *  1 - use the PhyNum field as a fallback to the mapping logic
+	 *  0 - never use the PhyNum field
+	 * -1 - only use the PhyNum field
+	 */
+	id = MPS_MAP_BAD_ID;
+	if (sc->use_phynum != -1) 
+		id = mps_mapping_get_sas_id(sc, sas_address, handle);
 	if (id == MPS_MAP_BAD_ID) {
-		printf("failure at %s:%d/%s()! Could not get ID for device "
-		    "with handle 0x%04x\n", __FILE__, __LINE__, __func__,
-		    handle);
-		error = ENXIO;
-		goto out;
+		if ((sc->use_phynum == 0)
+		 || ((id = config_page.PhyNum) > sassc->maxtargets)) {
+			mps_dprint(sc, MPS_INFO, "failure at %s:%d/%s()! "
+			    "Could not get ID for device with handle 0x%04x\n",
+			    __FILE__, __LINE__, __func__, handle);
+			error = ENXIO;
+			goto out;
+		}
 	}
 
 	if (mpssas_check_id(sassc, id) != 0) {
@@ -684,9 +695,16 @@ mpssas_add_device(struct mps_softc *sc, 
 		goto out;
 	}
 
+	targ = &sassc->targets[id];
+	if (targ->handle != 0x0) {
+		mps_dprint(sc, MPS_MAPPING, "Attempting to reuse target id "
+		    "%d handle 0x%04x\n", id, targ->handle);
+		error = ENXIO;
+		goto out;
+	}
+
 	mps_dprint(sc, MPS_MAPPING, "SAS Address from SAS device page0 = %jx\n",
 	    sas_address);
-	targ = &sassc->targets[id];
 	targ->devinfo = device_info;
 	targ->devname = le32toh(config_page.DeviceName.High);
 	targ->devname = (targ->devname << 32) | 

Modified: head/sys/dev/mps/mpsvar.h
==============================================================================
--- head/sys/dev/mps/mpsvar.h	Wed Nov  2 15:11:23 2016	(r308216)
+++ head/sys/dev/mps/mpsvar.h	Wed Nov  2 15:13:25 2016	(r308217)
@@ -285,6 +285,7 @@ struct mps_softc {
 	int				chain_free_lowwater;
 	u_int				enable_ssu;
 	int				spinup_wait_time;
+	int				use_phynum;
 	uint64_t			chain_alloc_fail;
 	struct sysctl_ctx_list		sysctl_ctx;
 	struct sysctl_oid		*sysctl_tree;


More information about the svn-src-all mailing list