Skip to content

Commit 004ce88

Browse files
ptrrkssnbsdimp
authored andcommitted
mpr: Add workaround for too few slots being automatically scanned
This patch adds a /boot/loader.conf setting that makes it possibly to override the detected number of slots in storage enclosures. Some (yes I'm looking at you HPE D6020!) reports less available slots that there actually are (the D6020 seems to report 18 but actually has 35 per drawer). This causes the mpr driver to have problems detecting/managing all drives in a multienclosure setting. For the D6020 this occurs when connecting two or more fully equipped (140 drives) enclosures to one controller... This problem can be "fixed" by adding the following to /boot/loader.conf and rebooting: hw.mpr.encl_min_slots="35" Note: I (Warner) don't have this hardware to see if there's some way to fix the detection, so I'm committing this as a stop-gap. It's a no-op if no tunable is set. PR: 271238 Reivewed by: imp
1 parent 58ce49d commit 004ce88

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

sys/dev/mpr/mpr.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,6 +1729,7 @@ mpr_get_tunables(struct mpr_softc *sc)
17291729
sc->enable_ssu = MPR_SSU_ENABLE_SSD_DISABLE_HDD;
17301730
sc->spinup_wait_time = DEFAULT_SPINUP_WAIT;
17311731
sc->use_phynum = 1;
1732+
sc->encl_min_slots = 0;
17321733
sc->max_reqframes = MPR_REQ_FRAMES;
17331734
sc->max_prireqframes = MPR_PRI_REQ_FRAMES;
17341735
sc->max_replyframes = MPR_REPLY_FRAMES;
@@ -1748,6 +1749,7 @@ mpr_get_tunables(struct mpr_softc *sc)
17481749
TUNABLE_INT_FETCH("hw.mpr.enable_ssu", &sc->enable_ssu);
17491750
TUNABLE_INT_FETCH("hw.mpr.spinup_wait_time", &sc->spinup_wait_time);
17501751
TUNABLE_INT_FETCH("hw.mpr.use_phy_num", &sc->use_phynum);
1752+
TUNABLE_INT_FETCH("hw.mpr.encl_min_slots", &sc->encl_min_slots);
17511753
TUNABLE_INT_FETCH("hw.mpr.max_reqframes", &sc->max_reqframes);
17521754
TUNABLE_INT_FETCH("hw.mpr.max_prireqframes", &sc->max_prireqframes);
17531755
TUNABLE_INT_FETCH("hw.mpr.max_replyframes", &sc->max_replyframes);
@@ -1797,6 +1799,10 @@ mpr_get_tunables(struct mpr_softc *sc)
17971799
device_get_unit(sc->mpr_dev));
17981800
TUNABLE_INT_FETCH(tmpstr, &sc->use_phynum);
17991801

1802+
snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.encl_min_slots",
1803+
device_get_unit(sc->mpr_dev));
1804+
TUNABLE_INT_FETCH(tmpstr, &sc->encl_min_slots);
1805+
18001806
snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.max_reqframes",
18011807
device_get_unit(sc->mpr_dev));
18021808
TUNABLE_INT_FETCH(tmpstr, &sc->max_reqframes);
@@ -1951,6 +1957,10 @@ mpr_setup_sysctl(struct mpr_softc *sc)
19511957
SYSCTL_ADD_UQUAD(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
19521958
OID_AUTO, "prp_page_alloc_fail", CTLFLAG_RD,
19531959
&sc->prp_page_alloc_fail, "PRP page allocation failures");
1960+
1961+
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
1962+
OID_AUTO, "encl_min_slots", CTLFLAG_RW, &sc->encl_min_slots, 0,
1963+
"force enclosure minimum slots");
19541964
}
19551965

19561966
static struct mpr_debug_string {

sys/dev/mpr/mpr_mapping.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2785,6 +2785,8 @@ mpr_mapping_enclosure_dev_status_change_event(struct mpr_softc *sc,
27852785
* DPM, if it's being used.
27862786
*/
27872787
if (enc_idx != MPR_ENCTABLE_BAD_IDX) {
2788+
u16 new_num_slots;
2789+
27882790
et_entry = &sc->enclosure_table[enc_idx];
27892791
if (et_entry->init_complete &&
27902792
!et_entry->missing_count) {
@@ -2796,6 +2798,17 @@ mpr_mapping_enclosure_dev_status_change_event(struct mpr_softc *sc,
27962798
et_entry->enc_handle = le16toh(event_data->
27972799
EnclosureHandle);
27982800
et_entry->start_slot = le16toh(event_data->StartSlot);
2801+
new_num_slots = le16toh(event_data->NumSlots);
2802+
if (new_num_slots < sc->encl_min_slots) {
2803+
mpr_dprint(sc, MPR_MAPPING, "%s: Enclosure %d num_slots %d, overriding with %d.\n",
2804+
__func__, enc_idx, new_num_slots, sc->encl_min_slots);
2805+
new_num_slots = sc->encl_min_slots;
2806+
}
2807+
if (et_entry->num_slots != new_num_slots) {
2808+
mpr_dprint(sc, MPR_MAPPING, "%s: Enclosure %d old num_slots %d, new %d.\n",
2809+
__func__, enc_idx, et_entry->num_slots, sc->encl_min_slots);
2810+
et_entry->num_slots = new_num_slots;
2811+
}
27992812
saved_phy_bits = et_entry->phy_bits;
28002813
et_entry->phy_bits |= le32toh(event_data->PhyBits);
28012814
if (saved_phy_bits != et_entry->phy_bits)
@@ -2858,6 +2871,11 @@ mpr_mapping_enclosure_dev_status_change_event(struct mpr_softc *sc,
28582871
et_entry->start_index = MPR_MAPTABLE_BAD_IDX;
28592872
et_entry->dpm_entry_num = MPR_DPM_BAD_IDX;
28602873
et_entry->num_slots = le16toh(event_data->NumSlots);
2874+
if (et_entry->num_slots < sc->encl_min_slots) {
2875+
mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: Enclosure %d num_slots is %d, overriding with %d.\n",
2876+
__func__, enc_idx, et_entry->num_slots, sc->encl_min_slots);
2877+
et_entry->num_slots = sc->encl_min_slots;
2878+
}
28612879
et_entry->start_slot = le16toh(event_data->StartSlot);
28622880
et_entry->phy_bits = le32toh(event_data->PhyBits);
28632881
}

sys/dev/mpr/mprvar.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ struct mpr_softc {
366366
int spinup_wait_time;
367367
int use_phynum;
368368
int dump_reqs_alltypes;
369+
int encl_min_slots;
369370
uint64_t chain_alloc_fail;
370371
uint64_t prp_page_alloc_fail;
371372
struct sysctl_ctx_list sysctl_ctx;

0 commit comments

Comments
 (0)