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
This commit is contained in:
parent
5ffb56f057
commit
4ab1cdc5ad
@ -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
|
||||
|
@ -757,14 +757,25 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
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) {
|
||||
device_printf(sc->mpr_dev, "Excluding target id %d\n", id);
|
||||
@ -772,9 +783,16 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
|
||||
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) |
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -669,14 +669,25 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
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) {
|
||||
device_printf(sc->mps_dev, "Excluding target id %d\n", id);
|
||||
@ -684,9 +695,16 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
|
||||
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) |
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user