summaryrefslogtreecommitdiff
path: root/drivers/edac/skx_common.c
diff options
context:
space:
mode:
authorQiuxu Zhuo <qiuxu.zhuo@intel.com>2022-09-01 22:43:08 +0300
committerTony Luck <tony.luck@intel.com>2022-09-08 21:40:00 +0300
commitfe32f366931a950889e8d72be86fafc867dab777 (patch)
treec344ae0f4860bfe62057ae67298a866a4f4740df /drivers/edac/skx_common.c
parent93df19476535a4ed871bc5eae719b6d67cf3abc3 (diff)
downloadlinux-fe32f366931a950889e8d72be86fafc867dab777.tar.xz
EDAC/skx_common: Use driver decoder first
The performance of driver decoder[1] is better than the performance of firmware decoder[2], especially on frequent correctable errors. So use the driver decoder first, fall back to firmware decoder if the driver decoder is unavailable. Also rename the function pointer skx_decode to driver_decode (better name to contrast with adxl_decode). [1] Decode errors by extracting error information from registers of memory controllers and/or MCA bank registers. [2] Decode errors by calling ACPI DSM methods. Co-developed-by: Youquan Song <youquan.song@intel.com> Signed-off-by: Youquan Song <youquan.song@intel.com> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com> Link: https://lore.kernel.org/all/20220901194310.115427-1-tony.luck@intel.com/
Diffstat (limited to 'drivers/edac/skx_common.c')
-rw-r--r--drivers/edac/skx_common.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c
index 19c17c5198c5..9b10c359849b 100644
--- a/drivers/edac/skx_common.c
+++ b/drivers/edac/skx_common.c
@@ -40,7 +40,7 @@ static char *adxl_msg;
static unsigned long adxl_nm_bitmap;
static char skx_msg[MSG_SIZE];
-static skx_decode_f skx_decode;
+static skx_decode_f driver_decode;
static skx_show_retry_log_f skx_show_retry_rd_err_log;
static u64 skx_tolm, skx_tohm;
static LIST_HEAD(dev_edac_list);
@@ -173,6 +173,8 @@ static bool skx_adxl_decode(struct decoded_addr *res, bool error_in_1st_level_me
break;
}
+ res->decoded_by_adxl = true;
+
return true;
}
@@ -183,7 +185,7 @@ void skx_set_mem_cfg(bool mem_cfg_2lm)
void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log)
{
- skx_decode = decode;
+ driver_decode = decode;
skx_show_retry_rd_err_log = show_retry_log;
}
@@ -591,7 +593,7 @@ static void skx_mce_output_error(struct mem_ctl_info *mci,
break;
}
}
- if (adxl_component_count) {
+ if (res->decoded_by_adxl) {
len = snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s",
overflow ? " OVERFLOW" : "",
(uncorrected_error && recoverable) ? " recoverable" : "",
@@ -651,11 +653,11 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
memset(&res, 0, sizeof(res));
res.addr = mce->addr;
- if (adxl_component_count) {
- if (!skx_adxl_decode(&res, skx_error_in_1st_level_mem(mce)))
+ /* Try driver decoder first */
+ if (!(driver_decode && driver_decode(&res))) {
+ /* Then try firmware decoder (ACPI DSM methods) */
+ if (!(adxl_component_count && skx_adxl_decode(&res, skx_error_in_1st_level_mem(mce))))
return NOTIFY_DONE;
- } else if (!skx_decode || !skx_decode(&res)) {
- return NOTIFY_DONE;
}
mci = res.dev->imc[res.imc].mci;