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-head
mailing list