EDAC, sb_edac: Early return on ADDRV bit and address type test
Subsystems (2)
Luck, Tony
maintainerPATCH v3 1/2 EDAC, sb_edac: Early return on ADDRV bit and address type test
From: Qiuxu Zhuo <[email protected]>
Users of the mce_register_decode_chain() are called for every logged error. EDAC drivers should check:
1) Is this a memory error? [bit 7 in status register]
2) Is there a valid address? [bit 58 in status register]
3) Is the address a system address? [bitfield 8:6 in misc register]
The sb_edac driver performed test "1" twice. Waited far too long to perform check "2". Didn't do check "3" at all.
Fix: Move the test for valid address from sbridge_mce_output_error() into sbridge_mce_check_error() and add a test for the type immediately after. Delete the redundant check for the type of the error from sbridge_mce_output_error()
[Tony: re-worded commit comment]
--- drivers/edac/sb_edac.c | 68 ++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 33 deletions(-)
drivers/edac/sb_edac.c +35 -33
@@ -2911,35 +2911,27 @@ static void sbridge_mce_output_error(struct mem_ctl_info *mci,* cccc = channel * If the mask doesn't match, report an error to the parsing logic */ -if (! ((errcode &0xef80 ) ==0x80 )) { - optype ="Can't parse: it is not a mem" ; - }else { -switch (optypenum) { -case 0 : - optype ="generic undef request error" ; -break ; -case 1 : - optype ="memory read error" ; -break ; -case 2 : - optype ="memory write error" ; -break ; -case 3 : - optype ="addr/cmd error" ; -break ; -case 4 : - optype ="memory scrubbing error" ; -break ; -default : - optype ="reserved" ; -break ; - } +switch (optypenum) { +case 0 : + optype ="generic undef request error" ; +break ; +case 1 : + optype ="memory read error" ; +break ; +case 2 : + optype ="memory write error" ; +break ; +case 3 : + optype ="addr/cmd error" ; +break ; +case 4 : + optype ="memory scrubbing error" ; +break ; +default : + optype ="reserved" ; +break ; } -/* Only decode errors with an valid address (ADDRV) */ -if (!GET_BITFIELD (m->status,58 ,58 )) -return ; -if (pvt->info.type ==KNIGHTS_LANDING ) {if (channel ==14 ) { edac_dbg(0, "%s%s err_code:%04x:%04x EDRAM bank %d\n",
@@ -3045,17 +3037,11 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val, {struct mce *mce = (struct mce *)data;struct mem_ctl_info *mci; -struct sbridge_pvt *pvt;char *type;if (edac_get_report_status () ==EDAC_REPORTING_DISABLED )return NOTIFY_DONE ; - mci =get_mci_for_node_id (mce->socketid,IMC0 ); -if (!mci) -return NOTIFY_DONE ; - pvt = mci->pvt_info; -/* * Just let mcelog handle it if the error is * outside the memory controller. A memory error
@@ -3065,6 +3051,22 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,if ((mce->status &0xefff ) >>7 !=1 )return NOTIFY_DONE ; +/* Check ADDRV bit in STATUS */ +if (!GET_BITFIELD (mce->status,58 ,58 )) +return NOTIFY_DONE ; + +/* Check MISCV bit in STATUS */ +if (!GET_BITFIELD (mce->status,59 ,59 )) +return NOTIFY_DONE ; + +/* Check address type in MISC (physical address only) */ +if (GET_BITFIELD (mce->misc,6 ,8 ) !=2 ) +return NOTIFY_DONE ; + + mci =get_mci_for_node_id (mce->socketid,IMC0 ); +if (!mci) +return NOTIFY_DONE ; +if (mce->mcgstatus &MCG_STATUS_MCIP ) type ="Exception" ;else