The threaded ISR handlers (thunderx_ocx_com_threaded_isr(), thunderx_ocx_lnk_threaded_isr(), and thunderx_l2c_threaded_isr()) build multi-line error reports by formatting register details into a scratch buffer and appending them to "msg" with strlcat().
In preparation for removing the deprecated strlcat() API[1], refactor the ISR handlers to construct error messages using struct seq_buf. Additionally, fix two bugs in decode_register(): initialize "str[0] = '\0'" so callers do not append stale buffer contents when no error bits match, and stop iterating if snprintf() truncates the buffer to avoid underflowing the remaining "size" counter. Link: https://github.com/KSPP/linux/issues/370 [1] Cc: [email protected] Assisted-by: AI:Claude-3-5-Sonnet [editor_update_file, shell_command_run] Signed-off-by: Bill Wendling <[email protected]> --- Cc: Russell King <[email protected]> Cc: Huacai Chen <[email protected]> Cc: WANG Xuerui <[email protected]> Cc: Thomas Bogendoerfer <[email protected]> Cc: "James E.J. Bottomley" <[email protected]> Cc: Helge Deller <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Dave Hansen <[email protected]> Cc: [email protected] Cc: "H. Peter Anvin" <[email protected]> Cc: Ian Abbott <[email protected]> Cc: H Hartley Sweeten <[email protected]> Cc: Tony Luck <[email protected]> Cc: Maarten Lankhorst <[email protected]> Cc: Maxime Ripard <[email protected]> Cc: Thomas Zimmermann <[email protected]> Cc: David Airlie <[email protected]> Cc: Simona Vetter <[email protected]> Cc: Matthew Brost <[email protected]> Cc: "Thomas Hellström" <[email protected]> Cc: Rodrigo Vivi <[email protected]> Cc: Dmitry Torokhov <[email protected]> Cc: Matthias Schwarzott <[email protected]> Cc: Mauro Carvalho Chehab <[email protected]> Cc: Tony Nguyen <[email protected]> Cc: Przemek Kitszel <[email protected]> Cc: Andrew Lunn <[email protected]> Cc: "David S. Miller" <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: Jakub Kicinski <[email protected]> Cc: Paolo Abeni <[email protected]> Cc: Arend van Spriel <[email protected]> Cc: Rob Herring <[email protected]> Cc: Saravana Kannan <[email protected]> Cc: Krzysztof Kozlowski <[email protected]> Cc: Sylwester Nawrocki <[email protected]> Cc: Peter Griffin <[email protected]> Cc: Alim Akhtar <[email protected]> Cc: Linus Walleij <[email protected]> Cc: Anil Gurumurthy <[email protected]> Cc: Sudarsana Kalluru <[email protected]> Cc: "Martin K. Petersen" <[email protected]> Cc: Trond Myklebust <[email protected]> Cc: Anna Schumaker <[email protected]> Cc: Mike Marshall <[email protected]> Cc: Martin Brandenburg <[email protected]> Cc: Kees Cook <[email protected]> Cc: Jiri Pirko <[email protected]> Cc: Simon Horman <[email protected]> Cc: Chuck Lever <[email protected]> Cc: Jeff Layton <[email protected]> Cc: NeilBrown <[email protected]> Cc: Olga Kornievskaia <[email protected]> Cc: Dai Ngo <[email protected]> Cc: Tom Talpey <[email protected]> Cc: Jaroslav Kysela <[email protected]> Cc: Takashi Iwai <[email protected]> Cc: Bill Wendling <[email protected]> Cc: Andrew Morton <[email protected]> Cc: "Mike Rapoport (Microsoft)" <[email protected]> Cc: Kanglong Wang <[email protected]> Cc: Tiezhu Yang <[email protected]> Cc: Qiang Ma <[email protected]> Cc: Randy Dunlap <[email protected]> Cc: Pengpeng Hou <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Breno Leitao <[email protected]> Cc: Thorsten Blum <[email protected]> Cc: Harshit Mogalapalli <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Lyude Paul <[email protected]> Cc: Ashutosh Desai <[email protected]> Cc: Imre Deak <[email protected]> Cc: Dmitry Baryshkov <[email protected]> Cc: Johan Hovold <[email protected]> Cc: Johannes Berg <[email protected]> Cc: Miri Korenblit <[email protected]> Cc: Alexander Stein <[email protected]> Cc: Cryolitia PukNgae <[email protected]> Cc: Jiaming Zhang <[email protected]> Cc: Will Porter <[email protected]> Cc: Cen Zhang <[email protected]> Cc: "Cássio Gabriel" <[email protected]> Cc: Rong Zhang <[email protected]> Cc: Arun Raghavan <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] --- drivers/edac/thunderx_edac.c | 64 ++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/drivers/edac/thunderx_edac.c b/drivers/edac/thunderx_edac.c index e7c335ca0c36..4e3781815b6d 100644 --- a/drivers/edac/thunderx_edac.c +++ b/drivers/edac/thunderx_edac.c @@ -20,6 +20,7 @@ #include <linux/atomic.h> #include <linux/bitfield.h> #include <linux/circ_buf.h> +#include <linux/seq_buf.h> #include <asm/page.h> @@ -47,12 +48,17 @@ static void decode_register(char *str, size_t size, { int ret = 0; + if (size > 0) + str[0] = '\0'; + while (descr->type && descr->mask && descr->descr) { if (reg & descr->mask) { ret = snprintf(str, size, "\n\t%s, %s", descr->type == ERR_CORRECTED ? "Corrected" : "Uncorrected", descr->descr); + if (ret < 0 || ret >= size) + break; str += ret; size -= ret; } @@ -1115,35 +1121,37 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id) while (CIRC_CNT(ocx->com_ring_head, ocx->com_ring_tail, ARRAY_SIZE(ocx->com_err_ctx))) { + struct seq_buf s; + tail = ring_pos(ocx->com_ring_tail, ARRAY_SIZE(ocx->com_err_ctx)); ctx = &ocx->com_err_ctx[tail]; - snprintf(msg, OCX_MESSAGE_SIZE, "%s: OCX_COM_INT: %016llx", - ocx->edac_dev->ctl_name, ctx->reg_com_int); + seq_buf_init(&s, msg, OCX_MESSAGE_SIZE); + + seq_buf_printf(&s, "%s: OCX_COM_INT: %016llx", + ocx->edac_dev->ctl_name, ctx->reg_com_int); decode_register(other, OCX_OTHER_SIZE, ocx_com_errors, ctx->reg_com_int); - strlcat(msg, other, OCX_MESSAGE_SIZE); + seq_buf_puts(&s, other); for (lane = 0; lane < OCX_RX_LANES; lane++) if (ctx->reg_com_int & BIT(lane)) { - snprintf(other, OCX_OTHER_SIZE, - "\n\tOCX_LNE_INT[%02d]: %016llx OCX_LNE_STAT11[%02d]: %016llx", - lane, ctx->reg_lane_int[lane], - lane, ctx->reg_lane_stat11[lane]); - - strlcat(msg, other, OCX_MESSAGE_SIZE); + seq_buf_printf(&s, + "\n\tOCX_LNE_INT[%02d]: %016llx OCX_LNE_STAT11[%02d]: %016llx", + lane, ctx->reg_lane_int[lane], + lane, ctx->reg_lane_stat11[lane]); decode_register(other, OCX_OTHER_SIZE, ocx_lane_errors, ctx->reg_lane_int[lane]); - strlcat(msg, other, OCX_MESSAGE_SIZE); + seq_buf_puts(&s, other); } if (ctx->reg_com_int & OCX_COM_INT_CE) - edac_device_handle_ce(ocx->edac_dev, 0, 0, msg); + edac_device_handle_ce(ocx->edac_dev, 0, 0, seq_buf_str(&s)); ocx->com_ring_tail++; } @@ -1196,25 +1204,28 @@ static irqreturn_t thunderx_ocx_lnk_threaded_isr(int irq, void *irq_id) while (CIRC_CNT(ocx->link_ring_head, ocx->link_ring_tail, ARRAY_SIZE(ocx->link_err_ctx))) { + struct seq_buf s; + tail = ring_pos(ocx->link_ring_head, ARRAY_SIZE(ocx->link_err_ctx)); ctx = &ocx->link_err_ctx[tail]; - snprintf(msg, OCX_MESSAGE_SIZE, - "%s: OCX_COM_LINK_INT[%d]: %016llx", - ocx->edac_dev->ctl_name, - ctx->link, ctx->reg_com_link_int); + seq_buf_init(&s, msg, OCX_MESSAGE_SIZE); + + seq_buf_printf(&s, "%s: OCX_COM_LINK_INT[%d]: %016llx", + ocx->edac_dev->ctl_name, + ctx->link, ctx->reg_com_link_int); decode_register(other, OCX_OTHER_SIZE, ocx_com_link_errors, ctx->reg_com_link_int); - strlcat(msg, other, OCX_MESSAGE_SIZE); + seq_buf_puts(&s, other); if (ctx->reg_com_link_int & OCX_COM_LINK_INT_UE) - edac_device_handle_ue(ocx->edac_dev, 0, 0, msg); + edac_device_handle_ue(ocx->edac_dev, 0, 0, seq_buf_str(&s)); else if (ctx->reg_com_link_int & OCX_COM_LINK_INT_CE) - edac_device_handle_ce(ocx->edac_dev, 0, 0, msg); + edac_device_handle_ce(ocx->edac_dev, 0, 0, seq_buf_str(&s)); ocx->link_ring_tail++; } @@ -1880,22 +1891,25 @@ static irqreturn_t thunderx_l2c_threaded_isr(int irq, void *irq_id) while (CIRC_CNT(l2c->ring_head, l2c->ring_tail, ARRAY_SIZE(l2c->err_ctx))) { + struct seq_buf s; + tail = ring_pos(l2c->ring_tail, ARRAY_SIZE(l2c->err_ctx)); ctx = &l2c->err_ctx[tail]; - snprintf(msg, L2C_MESSAGE_SIZE, - "%s: %s: %016llx, %s: %016llx", - l2c->edac_dev->ctl_name, reg_int_name, ctx->reg_int, - ctx->reg_ext_name, ctx->reg_ext); + seq_buf_init(&s, msg, L2C_MESSAGE_SIZE); + + seq_buf_printf(&s, "%s: %s: %016llx, %s: %016llx", + l2c->edac_dev->ctl_name, reg_int_name, ctx->reg_int, + ctx->reg_ext_name, ctx->reg_ext); decode_register(other, L2C_OTHER_SIZE, l2_errors, ctx->reg_int); - strlcat(msg, other, L2C_MESSAGE_SIZE); + seq_buf_puts(&s, other); if (ctx->reg_int & mask_ue) - edac_device_handle_ue(l2c->edac_dev, 0, 0, msg); + edac_device_handle_ue(l2c->edac_dev, 0, 0, seq_buf_str(&s)); else if (ctx->reg_int & mask_ce) - edac_device_handle_ce(l2c->edac_dev, 0, 0, msg); + edac_device_handle_ce(l2c->edac_dev, 0, 0, seq_buf_str(&s)); l2c->ring_tail++; } -- 2.55.0.1032.g73a4cd73de-goog
