diff options
author | Fan Wu <wufan@codeaurora.org> | 2018-09-18 21:59:00 -0400 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2018-09-22 12:35:40 -0400 |
commit | c798c88f3962ddff89c7aa818986caeecd46ab4c (patch) | |
tree | 4aab832133eed66ddd1d0e729b2f31e9d309b269 | |
parent | 6f6da136046294a1e8d2944336eb97412751f653 (diff) |
EDAC, ghes: Use CPER module handles to locate DIMMs
Use SMBIOS module handle type 17, on platforms which provide valid
ones, to locate the corresponding DIMM and thus have per-DIMM error
counter updates.
Signed-off-by: Fan Wu <wufan@codeaurora.org>
[ Massage commit message. ]
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Tyler Baicar <baicar.tyler@gmail.com>
Reviewed-by: James Morse <james.morse@arm.com>
Tested-by: Toshi Kani <toshi.kani@hpe.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: baicar.tyler@gmail.com
Cc: john.garry@huawei.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-edac <linux-edac@vger.kernel.org>
Cc: shiju.jose@huawei.com
Cc: tanxiaofei@huawei.com
Cc: wanghuiqiang@huawei.com
Link: http://lkml.kernel.org/r/1537322340-1860-1-git-send-email-wufan@codeaurora.org
-rw-r--r-- | drivers/edac/ghes_edac.c | 23 | ||||
-rw-r--r-- | include/linux/edac.h | 2 |
2 files changed, 25 insertions, 0 deletions
diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index 473aeec4b1da..49396bf6ad88 100644 --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c | |||
@@ -81,6 +81,18 @@ static void ghes_edac_count_dimms(const struct dmi_header *dh, void *arg) | |||
81 | (*num_dimm)++; | 81 | (*num_dimm)++; |
82 | } | 82 | } |
83 | 83 | ||
84 | static int get_dimm_smbios_index(u16 handle) | ||
85 | { | ||
86 | struct mem_ctl_info *mci = ghes_pvt->mci; | ||
87 | int i; | ||
88 | |||
89 | for (i = 0; i < mci->tot_dimms; i++) { | ||
90 | if (mci->dimms[i]->smbios_handle == handle) | ||
91 | return i; | ||
92 | } | ||
93 | return -1; | ||
94 | } | ||
95 | |||
84 | static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) | 96 | static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) |
85 | { | 97 | { |
86 | struct ghes_edac_dimm_fill *dimm_fill = arg; | 98 | struct ghes_edac_dimm_fill *dimm_fill = arg; |
@@ -177,6 +189,8 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) | |||
177 | entry->total_width, entry->data_width); | 189 | entry->total_width, entry->data_width); |
178 | } | 190 | } |
179 | 191 | ||
192 | dimm->smbios_handle = entry->handle; | ||
193 | |||
180 | dimm_fill->count++; | 194 | dimm_fill->count++; |
181 | } | 195 | } |
182 | } | 196 | } |
@@ -327,12 +341,21 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err) | |||
327 | p += sprintf(p, "bit_pos:%d ", mem_err->bit_pos); | 341 | p += sprintf(p, "bit_pos:%d ", mem_err->bit_pos); |
328 | if (mem_err->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) { | 342 | if (mem_err->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) { |
329 | const char *bank = NULL, *device = NULL; | 343 | const char *bank = NULL, *device = NULL; |
344 | int index = -1; | ||
345 | |||
330 | dmi_memdev_name(mem_err->mem_dev_handle, &bank, &device); | 346 | dmi_memdev_name(mem_err->mem_dev_handle, &bank, &device); |
331 | if (bank != NULL && device != NULL) | 347 | if (bank != NULL && device != NULL) |
332 | p += sprintf(p, "DIMM location:%s %s ", bank, device); | 348 | p += sprintf(p, "DIMM location:%s %s ", bank, device); |
333 | else | 349 | else |
334 | p += sprintf(p, "DIMM DMI handle: 0x%.4x ", | 350 | p += sprintf(p, "DIMM DMI handle: 0x%.4x ", |
335 | mem_err->mem_dev_handle); | 351 | mem_err->mem_dev_handle); |
352 | |||
353 | index = get_dimm_smbios_index(mem_err->mem_dev_handle); | ||
354 | if (index >= 0) { | ||
355 | e->top_layer = index; | ||
356 | e->enable_per_layer_report = true; | ||
357 | } | ||
358 | |||
336 | } | 359 | } |
337 | if (p > e->location) | 360 | if (p > e->location) |
338 | *(p - 1) = '\0'; | 361 | *(p - 1) = '\0'; |
diff --git a/include/linux/edac.h b/include/linux/edac.h index bffb97828ed6..a45ce1f84bfc 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h | |||
@@ -451,6 +451,8 @@ struct dimm_info { | |||
451 | u32 nr_pages; /* number of pages on this dimm */ | 451 | u32 nr_pages; /* number of pages on this dimm */ |
452 | 452 | ||
453 | unsigned csrow, cschannel; /* Points to the old API data */ | 453 | unsigned csrow, cschannel; /* Points to the old API data */ |
454 | |||
455 | u16 smbios_handle; /* Handle for SMBIOS type 17 */ | ||
454 | }; | 456 | }; |
455 | 457 | ||
456 | /** | 458 | /** |