From 22d4cbf6f7509f0aab58d60d488a0082916a2fb0 Mon Sep 17 00:00:00 2001 From: Ian Bridges Date: Wed, 29 Jul 2026 09:46:15 -0500 Subject: [PATCH] scsi: lpfc: Replace strlcat() with seq_buf in lpfc_rx_monitor_report() In preparation for removing the strlcat() API[1], replace its use in lpfc_rx_monitor_report(). The function accumulates one line per ring entry, which is what seq_buf is for. seq_buf tracks the write position, so the per entry strlen() rescans of the destination are gone. Each record is still formatted into the tmp buffer. seq_buf_puts() appends it only when it fits whole, so the output keeps ending at the last complete record. The loop still stops on overflow without consuming the current entry, and the returned count and the ring head keep their old meaning. The produced bytes are unchanged. Link: https://github.com/KSPP/linux/issues/370 [1] Signed-off-by: Ian Bridges Link: https://patch.msgid.link/20260729144617.1388646-4-icb@fastmail.org Reviewed-by: Nigel Kirkland Signed-off-by: Martin K. Petersen (Oracle) --- drivers/scsi/lpfc/lpfc_sli.c | 43 ++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 62a30a92b792..cfa4371169f1 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -8109,17 +8110,18 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba, u32 cnt = 0; char tmp[DBG_LOG_STR_SZ] = {0}; bool log_to_kmsg = (!buf || !buf_len) ? true : false; + struct seq_buf s; if (!log_to_kmsg) { /* clear the buffer to be sure */ memset(buf, 0, buf_len); - scnprintf(buf, buf_len, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s" - "%-8s%-8s%-8s%-16s\n", - "MaxBPI", "Tot_Data_CMF", - "Tot_Data_Cmd", "Tot_Data_Cmpl", - "Lat(us)", "Avg_IO", "Max_IO", "Bsy", - "IO_cnt", "Info", "BWutil(ms)"); + seq_buf_init(&s, buf, buf_len); + seq_buf_printf(&s, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s%-8s%-8s%-8s%-16s\n", + "MaxBPI", "Tot_Data_CMF", + "Tot_Data_Cmd", "Tot_Data_Cmpl", + "Lat(us)", "Avg_IO", "Max_IO", "Bsy", + "IO_cnt", "Info", "BWutil(ms)"); } /* Needs to be _irq because record is called from timer interrupt @@ -8131,24 +8133,27 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba, /* Read out this entry's data. */ if (!log_to_kmsg) { - /* If !log_to_kmsg, then store to buf. */ + /* + * Drop a record whole if it does not fit, without + * consuming its ring entry. + */ scnprintf(tmp, sizeof(tmp), - "%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu" - "%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n", - *head_idx, entry->max_bytes_per_interval, - entry->cmf_bytes, entry->total_bytes, - entry->rcv_bytes, entry->avg_io_latency, - entry->avg_io_size, entry->max_read_cnt, + "%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n", + *head_idx, + entry->max_bytes_per_interval, + entry->cmf_bytes, + entry->total_bytes, + entry->rcv_bytes, + entry->avg_io_latency, + entry->avg_io_size, + entry->max_read_cnt, entry->cmf_busy, entry->io_cnt, - entry->cmf_info, entry->timer_utilization, + entry->cmf_info, + entry->timer_utilization, entry->timer_interval); - /* Check for buffer overflow */ - if ((strlen(buf) + strlen(tmp)) >= buf_len) + if (seq_buf_puts(&s, tmp) < 0) break; - - /* Append entry's data to buffer */ - strlcat(buf, tmp, buf_len); } else { lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, "4410 %02u: MBPI %llu Xmit %llu "