From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752961AbdGYPsU (ORCPT ); Tue, 25 Jul 2017 11:48:20 -0400 Received: from mail.skyhub.de ([5.9.137.197]:53034 "EHLO mail.skyhub.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752933AbdGYPsS (ORCPT ); Tue, 25 Jul 2017 11:48:18 -0400 From: Borislav Petkov To: linux-edac Cc: Steven Rostedt , Tony Luck , Yazen Ghannam , X86 ML , LKML Subject: [RFC PATCH 6/8] EDAC, mce_amd: Convert to seq_buf Date: Tue, 25 Jul 2017 17:45:59 +0200 Message-Id: <20170725154601.27427-7-bp@alien8.de> X-Mailer: git-send-email 2.14.0.rc0 In-Reply-To: <20170725154601.27427-1-bp@alien8.de> References: <20170725154601.27427-1-bp@alien8.de> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Borislav Petkov Convert the part which decodes the error description to the sequence buffer facility and thus save ourselves the many printk() invocations building the decoded string. No functionality change. Signed-off-by: Borislav Petkov --- drivers/edac/mce_amd.c | 203 ++++++++++++++++++++++++++----------------------- 1 file changed, 108 insertions(+), 95 deletions(-) diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index a11a671c7a38..1f5e9bb161f3 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c @@ -1,3 +1,4 @@ +#include #include #include @@ -306,6 +307,11 @@ static struct smca_mce_desc smca_mce_descs[] = { [SMCA_SMU] = { smca_smu_mce_desc, ARRAY_SIZE(smca_smu_mce_desc) }, }; +/* 128 because, well, nice and round - two cachelines. */ +#define BUF_LEN 128 +static char __err_buf[BUF_LEN]; +static struct seq_buf sb; + static bool f12h_mc0_mce(u16 ec, u8 xec) { bool ret = false; @@ -315,9 +321,9 @@ static bool f12h_mc0_mce(u16 ec, u8 xec) ret = true; if (ll == LL_L2) - pr_cont("during L1 linefill from L2.\n"); + seq_buf_printf(&sb, "during L1 linefill from L2.\n"); else if (ll == LL_L1) - pr_cont("Data/Tag %s error.\n", R4_MSG(ec)); + seq_buf_printf(&sb, "Data/Tag %s error.\n", R4_MSG(ec)); else ret = false; } @@ -327,7 +333,7 @@ static bool f12h_mc0_mce(u16 ec, u8 xec) static bool f10h_mc0_mce(u16 ec, u8 xec) { if (R4(ec) == R4_GEN && LL(ec) == LL_L1) { - pr_cont("during data scrub.\n"); + seq_buf_printf(&sb, "during data scrub.\n"); return true; } return f12h_mc0_mce(ec, xec); @@ -336,7 +342,7 @@ static bool f10h_mc0_mce(u16 ec, u8 xec) static bool k8_mc0_mce(u16 ec, u8 xec) { if (BUS_ERROR(ec)) { - pr_cont("during system linefill.\n"); + seq_buf_printf(&sb, "during system linefill.\n"); return true; } @@ -356,14 +362,14 @@ static bool cat_mc0_mce(u16 ec, u8 xec) switch (r4) { case R4_DRD: case R4_DWR: - pr_cont("Data/Tag parity error due to %s.\n", - (r4 == R4_DRD ? "load/hw prf" : "store")); + seq_buf_printf(&sb, "Data/Tag parity error due to %s.\n", + (r4 == R4_DRD ? "load/hw prf" : "store")); break; case R4_EVICT: - pr_cont("Copyback parity error on a tag miss.\n"); + seq_buf_printf(&sb, "Copyback parity error on a tag miss.\n"); break; case R4_SNOOP: - pr_cont("Tag parity error during snoop.\n"); + seq_buf_printf(&sb, "Tag parity error during snoop.\n"); break; default: ret = false; @@ -373,17 +379,17 @@ static bool cat_mc0_mce(u16 ec, u8 xec) if ((II(ec) != II_MEM && II(ec) != II_IO) || LL(ec) != LL_LG) return false; - pr_cont("System read data error on a "); + seq_buf_printf(&sb, "System read data error on a "); switch (r4) { case R4_RD: - pr_cont("TLB reload.\n"); + seq_buf_printf(&sb, "TLB reload.\n"); break; case R4_DWR: - pr_cont("store.\n"); + seq_buf_printf(&sb, "store.\n"); break; case R4_DRD: - pr_cont("load.\n"); + seq_buf_printf(&sb, "load.\n"); break; default: ret = false; @@ -403,28 +409,28 @@ static bool f15h_mc0_mce(u16 ec, u8 xec) switch (xec) { case 0x0: - pr_cont("Data Array access error.\n"); + seq_buf_printf(&sb, "Data Array access error.\n"); break; case 0x1: - pr_cont("UC error during a linefill from L2/NB.\n"); + seq_buf_printf(&sb, "UC error during a linefill from L2/NB.\n"); break; case 0x2: case 0x11: - pr_cont("STQ access error.\n"); + seq_buf_printf(&sb, "STQ access error.\n"); break; case 0x3: - pr_cont("SCB access error.\n"); + seq_buf_printf(&sb, "SCB access error.\n"); break; case 0x10: - pr_cont("Tag error.\n"); + seq_buf_printf(&sb, "Tag error.\n"); break; case 0x12: - pr_cont("LDQ access error.\n"); + seq_buf_printf(&sb, "LDQ access error.\n"); break; default: @@ -433,12 +439,12 @@ static bool f15h_mc0_mce(u16 ec, u8 xec) } else if (BUS_ERROR(ec)) { if (!xec) - pr_cont("System Read Data Error.\n"); + seq_buf_printf(&sb, "System Read Data Error.\n"); else - pr_cont(" Internal error condition type %d.\n", xec); + seq_buf_printf(&sb, " Internal error condition type %d.\n", xec); } else if (INT_ERROR(ec)) { if (xec <= 0x1f) - pr_cont("Hardware Assert.\n"); + seq_buf_printf(&sb, "Hardware Assert.\n"); else ret = false; @@ -453,13 +459,13 @@ static void decode_mc0_mce(struct mce *m) u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); - pr_emerg(HW_ERR "MC0 Error: "); + seq_buf_printf(&sb, HW_ERR "MC0 Error: "); /* TLB error signatures are the same across families */ if (TLB_ERROR(ec)) { if (TT(ec) == TT_DATA) { - pr_cont("%s TLB %s.\n", LL_MSG(ec), - ((xec == 2) ? "locked miss" + seq_buf_printf(&sb, "%s TLB %s.\n", LL_MSG(ec), + ((xec == 2) ? "locked miss" : (xec ? "multimatch" : "parity"))); return; } @@ -478,19 +484,19 @@ static bool k8_mc1_mce(u16 ec, u8 xec) return false; if (ll == 0x2) - pr_cont("during a linefill from L2.\n"); + seq_buf_printf(&sb, "during a linefill from L2.\n"); else if (ll == 0x1) { switch (R4(ec)) { case R4_IRD: - pr_cont("Parity error during data load.\n"); + seq_buf_printf(&sb, "Parity error during data load.\n"); break; case R4_EVICT: - pr_cont("Copyback Parity/Victim error.\n"); + seq_buf_printf(&sb, "Copyback Parity/Victim error.\n"); break; case R4_SNOOP: - pr_cont("Tag Snoop error.\n"); + seq_buf_printf(&sb, "Tag Snoop error.\n"); break; default: @@ -515,13 +521,13 @@ static bool cat_mc1_mce(u16 ec, u8 xec) return false; if (r4 == R4_IRD) - pr_cont("Data/tag array parity error for a tag hit.\n"); + seq_buf_printf(&sb, "Data/tag array parity error for a tag hit.\n"); else if (r4 == R4_SNOOP) - pr_cont("Tag error during snoop/victimization.\n"); + seq_buf_printf(&sb, "Tag error during snoop/victimization.\n"); else if (xec == 0x0) - pr_cont("Tag parity error from victim castout.\n"); + seq_buf_printf(&sb, "Tag parity error from victim castout.\n"); else if (xec == 0x2) - pr_cont("Microcode patch RAM parity error.\n"); + seq_buf_printf(&sb, "Microcode patch RAM parity error.\n"); else ret = false; @@ -537,19 +543,19 @@ static bool f15h_mc1_mce(u16 ec, u8 xec) switch (xec) { case 0x0 ... 0xa: - pr_cont("%s.\n", f15h_mc1_mce_desc[xec]); + seq_buf_printf(&sb, "%s.\n", f15h_mc1_mce_desc[xec]); break; case 0xd: - pr_cont("%s.\n", f15h_mc1_mce_desc[xec-2]); + seq_buf_printf(&sb, "%s.\n", f15h_mc1_mce_desc[xec-2]); break; case 0x10: - pr_cont("%s.\n", f15h_mc1_mce_desc[xec-4]); + seq_buf_printf(&sb, "%s.\n", f15h_mc1_mce_desc[xec-4]); break; case 0x11 ... 0x15: - pr_cont("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]); + seq_buf_printf(&sb, "Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]); break; default: @@ -563,18 +569,18 @@ static void decode_mc1_mce(struct mce *m) u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); - pr_emerg(HW_ERR "MC1 Error: "); + seq_buf_printf(&sb, HW_ERR "MC1 Error: "); if (TLB_ERROR(ec)) - pr_cont("%s TLB %s.\n", LL_MSG(ec), - (xec ? "multimatch" : "parity error")); + seq_buf_printf(&sb, "%s TLB %s.\n", LL_MSG(ec), + (xec ? "multimatch" : "parity error")); else if (BUS_ERROR(ec)) { bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58))); - pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read")); + seq_buf_printf(&sb, "during %s.\n", (k8 ? "system linefill" : "NB data read")); } else if (INT_ERROR(ec)) { if (xec <= 0x3f) - pr_cont("Hardware Assert.\n"); + seq_buf_printf(&sb, "Hardware Assert.\n"); else goto wrong_mc1_mce; } else if (fam_ops->mc1_mce(ec, xec)) @@ -593,27 +599,27 @@ static bool k8_mc2_mce(u16 ec, u8 xec) bool ret = true; if (xec == 0x1) - pr_cont(" in the write data buffers.\n"); + seq_buf_printf(&sb, " in the write data buffers.\n"); else if (xec == 0x3) - pr_cont(" in the victim data buffers.\n"); + seq_buf_printf(&sb, " in the victim data buffers.\n"); else if (xec == 0x2 && MEM_ERROR(ec)) - pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec)); + seq_buf_printf(&sb, ": %s error in the L2 cache tags.\n", R4_MSG(ec)); else if (xec == 0x0) { if (TLB_ERROR(ec)) - pr_cont("%s error in a Page Descriptor Cache or Guest TLB.\n", - TT_MSG(ec)); + seq_buf_printf(&sb, "%s error in a Page Descriptor Cache or Guest TLB.\n", + TT_MSG(ec)); else if (BUS_ERROR(ec)) - pr_cont(": %s/ECC error in data read from NB: %s.\n", - R4_MSG(ec), PP_MSG(ec)); + seq_buf_printf(&sb, ": %s/ECC error in data read from NB: %s.\n", + R4_MSG(ec), PP_MSG(ec)); else if (MEM_ERROR(ec)) { u8 r4 = R4(ec); if (r4 >= 0x7) - pr_cont(": %s error during data copyback.\n", - R4_MSG(ec)); + seq_buf_printf(&sb, ": %s error during data copyback.\n", + R4_MSG(ec)); else if (r4 <= 0x1) - pr_cont(": %s parity/ECC error during data " - "access from L2.\n", R4_MSG(ec)); + seq_buf_printf(&sb, +": %s parity/ECC error during data access from L2.\n", R4_MSG(ec)); else ret = false; } else @@ -630,24 +636,24 @@ static bool f15h_mc2_mce(u16 ec, u8 xec) if (TLB_ERROR(ec)) { if (xec == 0x0) - pr_cont("Data parity TLB read error.\n"); + seq_buf_printf(&sb, "Data parity TLB read error.\n"); else if (xec == 0x1) - pr_cont("Poison data provided for TLB fill.\n"); + seq_buf_printf(&sb, "Poison data provided for TLB fill.\n"); else ret = false; } else if (BUS_ERROR(ec)) { if (xec > 2) ret = false; - pr_cont("Error during attempted NB data read.\n"); + seq_buf_printf(&sb, "Error during attempted NB data read.\n"); } else if (MEM_ERROR(ec)) { switch (xec) { case 0x4 ... 0xc: - pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x4]); + seq_buf_printf(&sb, "%s.\n", f15h_mc2_mce_desc[xec - 0x4]); break; case 0x10 ... 0x14: - pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x7]); + seq_buf_printf(&sb, "%s.\n", f15h_mc2_mce_desc[xec - 0x7]); break; default: @@ -655,7 +661,7 @@ static bool f15h_mc2_mce(u16 ec, u8 xec) } } else if (INT_ERROR(ec)) { if (xec <= 0x3f) - pr_cont("Hardware Assert.\n"); + seq_buf_printf(&sb, "Hardware Assert.\n"); else ret = false; } @@ -672,29 +678,29 @@ static bool f16h_mc2_mce(u16 ec, u8 xec) switch (xec) { case 0x04 ... 0x05: - pr_cont("%cBUFF parity error.\n", (r4 == R4_RD) ? 'I' : 'O'); + seq_buf_printf(&sb, "%cBUFF parity error.\n", (r4 == R4_RD) ? 'I' : 'O'); break; case 0x09 ... 0x0b: case 0x0d ... 0x0f: - pr_cont("ECC error in L2 tag (%s).\n", - ((r4 == R4_GEN) ? "BankReq" : - ((r4 == R4_SNOOP) ? "Prb" : "Fill"))); + seq_buf_printf(&sb, "ECC error in L2 tag (%s).\n", + ((r4 == R4_GEN) ? "BankReq" : + ((r4 == R4_SNOOP) ? "Prb" : "Fill"))); break; case 0x10 ... 0x19: case 0x1b: - pr_cont("ECC error in L2 data array (%s).\n", - (((r4 == R4_RD) && !(xec & 0x3)) ? "Hit" : - ((r4 == R4_GEN) ? "Attr" : - ((r4 == R4_EVICT) ? "Vict" : "Fill")))); + seq_buf_printf(&sb, "ECC error in L2 data array (%s).\n", + (((r4 == R4_RD) && !(xec & 0x3)) ? "Hit" : + ((r4 == R4_GEN) ? "Attr" : + ((r4 == R4_EVICT) ? "Vict" : "Fill")))); break; case 0x1c ... 0x1d: case 0x1f: - pr_cont("Parity error in L2 attribute bits (%s).\n", - ((r4 == R4_RD) ? "Hit" : - ((r4 == R4_GEN) ? "Attr" : "Fill"))); + seq_buf_printf(&sb, "Parity error in L2 attribute bits (%s).\n", + ((r4 == R4_RD) ? "Hit" : + ((r4 == R4_GEN) ? "Attr" : "Fill"))); break; default: @@ -709,10 +715,10 @@ static void decode_mc2_mce(struct mce *m) u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); - pr_emerg(HW_ERR "MC2 Error: "); + seq_buf_printf(&sb, HW_ERR "MC2 Error: "); if (!fam_ops->mc2_mce(ec, xec)) - pr_cont(HW_ERR "Corrupted MC2 MCE info?\n"); + pr_emerg(HW_ERR "Corrupted MC2 MCE info?\n"); } static void decode_mc3_mce(struct mce *m) @@ -726,7 +732,7 @@ static void decode_mc3_mce(struct mce *m) return; } - pr_emerg(HW_ERR "MC3 Error"); + seq_buf_printf(&sb, HW_ERR "MC3 Error"); if (xec == 0x0) { u8 r4 = R4(ec); @@ -734,7 +740,7 @@ static void decode_mc3_mce(struct mce *m) if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR)) goto wrong_mc3_mce; - pr_cont(" during %s.\n", R4_MSG(ec)); + seq_buf_printf(&sb, " during %s.\n", R4_MSG(ec)); } else goto wrong_mc3_mce; @@ -752,7 +758,7 @@ static void decode_mc4_mce(struct mce *m) u8 xec = XEC(m->status, 0x1f); u8 offset = 0; - pr_emerg(HW_ERR "MC4 Error (node %d): ", node_id); + seq_buf_printf(&sb, HW_ERR "MC4 Error (node %d): ", node_id); switch (xec) { case 0x0 ... 0xe: @@ -763,7 +769,7 @@ static void decode_mc4_mce(struct mce *m) if (fam == 0x11) goto wrong_mc4_mce; - pr_cont("%s.\n", mc4_mce_desc[xec]); + seq_buf_printf(&sb, "%s.\n", mc4_mce_desc[xec]); if (decode_dram_ecc) decode_dram_ecc(node_id, m); @@ -773,16 +779,16 @@ static void decode_mc4_mce(struct mce *m) case 0xf: if (TLB_ERROR(ec)) - pr_cont("GART Table Walk data error.\n"); + seq_buf_printf(&sb, "GART Table Walk data error.\n"); else if (BUS_ERROR(ec)) - pr_cont("DMA Exclusion Vector Table Walk error.\n"); + seq_buf_printf(&sb, "DMA Exclusion Vector Table Walk error.\n"); else goto wrong_mc4_mce; return; case 0x19: if (fam == 0x15 || fam == 0x16) - pr_cont("Compute Unit Data Error.\n"); + seq_buf_printf(&sb, "Compute Unit Data Error.\n"); else goto wrong_mc4_mce; return; @@ -795,7 +801,7 @@ static void decode_mc4_mce(struct mce *m) goto wrong_mc4_mce; } - pr_cont("%s.\n", mc4_mce_desc[xec - offset]); + seq_buf_printf(&sb, "%s.\n", mc4_mce_desc[xec - offset]); return; wrong_mc4_mce: @@ -811,20 +817,20 @@ static void decode_mc5_mce(struct mce *m) if (fam == 0xf || fam == 0x11) goto wrong_mc5_mce; - pr_emerg(HW_ERR "MC5 Error: "); + seq_buf_printf(&sb, HW_ERR "MC5 Error: "); if (INT_ERROR(ec)) { if (xec <= 0x1f) { - pr_cont("Hardware Assert.\n"); + seq_buf_printf(&sb, "Hardware Assert.\n"); return; } else goto wrong_mc5_mce; } if (xec == 0x0 || xec == 0xc) - pr_cont("%s.\n", mc5_mce_desc[xec]); + seq_buf_printf(&sb, "%s.\n", mc5_mce_desc[xec]); else if (xec <= 0xd) - pr_cont("%s parity error.\n", mc5_mce_desc[xec]); + seq_buf_printf(&sb, "%s parity error.\n", mc5_mce_desc[xec]); else goto wrong_mc5_mce; @@ -838,12 +844,12 @@ static void decode_mc6_mce(struct mce *m) { u8 xec = XEC(m->status, xec_mask); - pr_emerg(HW_ERR "MC6 Error: "); + seq_buf_printf(&sb, HW_ERR "MC6 Error: "); if (xec > 0x5) goto wrong_mc6_mce; - pr_cont("%s parity error.\n", mc6_mce_desc[xec]); + seq_buf_printf(&sb, "%s parity error.\n", mc6_mce_desc[xec]); return; wrong_mc6_mce: @@ -871,13 +877,13 @@ static void decode_smca_error(struct mce *m) bank_type = hwid->bank_type; ip_name = smca_get_long_name(bank_type); - pr_emerg(HW_ERR "%s Extended Error Code: %d\n", ip_name, xec); + seq_buf_printf(&sb, HW_ERR "%s Extended Error Code: %d\n", ip_name, xec); /* Only print the decode of valid error codes */ if (xec < smca_mce_descs[bank_type].num_descs && (hwid->xec_bitmap & BIT_ULL(xec))) { - pr_emerg(HW_ERR "%s Error: ", ip_name); - pr_cont("%s.\n", smca_mce_descs[bank_type].descs[xec]); + seq_buf_printf(&sb, HW_ERR "%s Error: ", ip_name); + seq_buf_printf(&sb, "%s.\n", smca_mce_descs[bank_type].descs[xec]); } if (bank_type == SMCA_UMC && xec == 0 && decode_dram_ecc) @@ -887,25 +893,25 @@ static void decode_smca_error(struct mce *m) static inline void amd_decode_err_code(u16 ec) { if (INT_ERROR(ec)) { - pr_emerg(HW_ERR "internal: %s\n", UU_MSG(ec)); + seq_buf_printf(&sb, HW_ERR "internal: %s\n", UU_MSG(ec)); return; } - pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec)); + seq_buf_printf(&sb, HW_ERR "cache level: %s", LL_MSG(ec)); if (BUS_ERROR(ec)) - pr_cont(", mem/io: %s", II_MSG(ec)); + seq_buf_printf(&sb, ", mem/io: %s", II_MSG(ec)); else - pr_cont(", tx: %s", TT_MSG(ec)); + seq_buf_printf(&sb, ", tx: %s", TT_MSG(ec)); if (MEM_ERROR(ec) || BUS_ERROR(ec)) { - pr_cont(", mem-tx: %s", R4_MSG(ec)); + seq_buf_printf(&sb, ", mem-tx: %s", R4_MSG(ec)); if (BUS_ERROR(ec)) - pr_cont(", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec)); + seq_buf_printf(&sb, ", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec)); } - pr_cont("\n"); + seq_buf_printf(&sb, "\n"); } /* @@ -948,6 +954,9 @@ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) if (amd_filter_mce(m)) return NOTIFY_STOP; + /* \0 terminated */ + seq_buf_init(&sb, __err_buf, BUF_LEN); + pr_emerg(HW_ERR "%s\n", decode_error_status(m)); pr_emerg(HW_ERR "CPU:%d (%x:%x:%x) MC%d_STATUS[%s|%s|%s|%s|%s", @@ -1044,6 +1053,10 @@ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) err_code: amd_decode_err_code(m->status & 0xffff); + pr_emerg("%.*s\n", (int)sb.len, sb.buffer); + + seq_buf_clear_buf(&sb); + return NOTIFY_STOP; } -- 2.14.0.rc0