[PATCH v2 18/24] EDAC, ghes: Fill sysfs with the DMI DIMM label information

Robert Richter
2019-06-24T15:09:46Z

This patch extracts the DIMM label from the DMI table and puts this
information into sysfs. E.g. on a ThunderX2 system we found this now:

# grep . /sys/devices/system/edac/mc/mc*/dimm*/dimm_label
/sys/devices/system/edac/mc/mc0/dimm0/dimm_label:N0 DIMM_A0
/sys/devices/system/edac/mc/mc0/dimm1/dimm_label:N0 DIMM_B0
/sys/devices/system/edac/mc/mc0/dimm2/dimm_label:N0 DIMM_C0
/sys/devices/system/edac/mc/mc0/dimm3/dimm_label:N0 DIMM_D0
/sys/devices/system/edac/mc/mc0/dimm4/dimm_label:N0 DIMM_E0
/sys/devices/system/edac/mc/mc0/dimm5/dimm_label:N0 DIMM_F0
/sys/devices/system/edac/mc/mc0/dimm6/dimm_label:N0 DIMM_G0
/sys/devices/system/edac/mc/mc0/dimm7/dimm_label:N0 DIMM_H0
/sys/devices/system/edac/mc/mc1/dimm0/dimm_label:N1 DIMM_I0
/sys/devices/system/edac/mc/mc1/dimm1/dimm_label:N1 DIMM_J0
/sys/devices/system/edac/mc/mc1/dimm2/dimm_label:N1 DIMM_K0
/sys/devices/system/edac/mc/mc1/dimm3/dimm_label:N1 DIMM_L0
/sys/devices/system/edac/mc/mc1/dimm4/dimm_label:N1 DIMM_M0
/sys/devices/system/edac/mc/mc1/dimm5/dimm_label:N1 DIMM_N0
/sys/devices/system/edac/mc/mc1/dimm6/dimm_label:N1 DIMM_O0
/sys/devices/system/edac/mc/mc1/dimm7/dimm_label:N1 DIMM_P0

Signed-off-by: Robert Richter <rrichter@marvell.com>
---
drivers/edac/ghes_edac.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
index 63de11654649..9c3495f7365b 100644
--- a/drivers/edac/ghes_edac.c
+++ b/drivers/edac/ghes_edac.c
@@ -265,10 +265,6 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg)
dimm->dtype = DEV_UNKNOWN;
dimm->grain = 128; /* Likely, worse case */

- /*
- * FIXME: It shouldn't be hard to also fill the DIMM labels
- */
-
if (dimm->nr_pages) {
edac_dbg(1, "DIMM%i: %s size = %d MB%s\n",
mi->idx, edac_mem_types[dimm->mtype],
@@ -302,6 +298,7 @@ static int mem_info_setup(void)
{
struct ghes_dimm_info *dimm;
bool enable_numa = true;
+ const char *bank, *device;
int num = 0;
int idx = 0;
int ret;
@@ -317,13 +314,27 @@ static int mem_info_setup(void)
dmi_walk(ghes_edac_set_nid, NULL);

for_each_dimm(dimm) {
+ bank = device = NULL;
+ dmi_memdev_name(dimm->dimm_info.smbios_handle,
+ &bank, &device);
+ if (bank && device) {
+ snprintf(dimm->dimm_info.label,
+ sizeof(dimm->dimm_info.label),
+ "%s %s", bank, device);
+ } else {
+ *dimm->dimm_info.label = '\0';
+ }
+
if (dimm->numa_node == NUMA_NO_NODE)
enable_numa = false;
else
mem_info.dimms_per_node[dimm->numa_node]++;

- edac_dbg(1, "DIMM%i: Found mem range [%pa-%pa] on node %d\n",
- dimm->idx, &dimm->start, &dimm->end, dimm->numa_node);
+ edac_dbg(1, "DIMM%i: Found mem range [%pa-%pa] on node %d, handle: 0x%.4x%s%s\n",
+ dimm->idx, &dimm->start, &dimm->end, dimm->numa_node,
+ dimm->dimm_info.smbios_handle,
+ *dimm->dimm_info.label ? ", label: " : "",
+ dimm->dimm_info.label);
}

if (enable_numa)
@@ -381,6 +392,9 @@ static void mem_info_prepare_mci(struct mem_ctl_info *mci)
mci_dimm->dtype = dmi_dimm->dtype;
mci_dimm->grain = dmi_dimm->grain;
mci_dimm->smbios_handle = dmi_dimm->smbios_handle;
+
+ if (*dmi_dimm->label)
+ strcpy(mci_dimm->label, dmi_dimm->label);
}

if (index != mci->tot_dimms)
--
2.20.1