From 06d3c77c520b8c3ddcfd11c75f92f91213f7078a Mon Sep 17 00:00:00 2001 From: Justin Tee Date: Mon, 15 Sep 2025 11:08:06 -0700 Subject: scsi: lpfc: Fix memory leak when nvmeio_trc debugfs entry is used Right after phba->nvmeio_trc is kzalloc'ed, phba->nvmeio_trc is set to NULL and the memory reference to free the kzalloc'ed memory is lost. Remove the phba->nvmeio_trc NULL ptr assignment after kzalloc. phba->nvmeio_trc is freed in lpfc_debugfs_terminate. Signed-off-by: Justin Tee Message-ID: <20250915180811.137530-10-justintee8345@gmail.com> Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_debugfs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/scsi/lpfc/lpfc_debugfs.c') diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 2db8d9529b8f..7c4d7bb3a56f 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -6280,7 +6280,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) } phba->nvmeio_trc_on = 1; phba->nvmeio_trc_output_idx = 0; - phba->nvmeio_trc = NULL; } else { nvmeio_off: phba->nvmeio_trc_size = 0; -- cgit v1.2.3 From 5d7ef44d8ae3b94565e8212d68c06bcee6f6ef90 Mon Sep 17 00:00:00 2001 From: Justin Tee Date: Mon, 15 Sep 2025 11:08:07 -0700 Subject: scsi: lpfc: Use switch case statements in DIF debugfs handlers With the introduction of aux numbers for debugfs entries, there's no need to use the if-else-if clause based on debugfs entry pointers. Update both the lpfc_debugfs_dif_err_read and lpfc_debugfs_dif_err_write routines to use switch case based on aux instead. Reported-by: Al Viro Closes: https://lore.kernel.org/linux-fsdevel/20250702212917.GK3406663@ZenIV/ Signed-off-by: Justin Tee Message-ID: <20250915180811.137530-11-justintee8345@gmail.com> Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_debugfs.c | 140 +++++++++++++++++++++++---------------- drivers/scsi/lpfc/lpfc_hw.h | 1 + 2 files changed, 83 insertions(+), 58 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_debugfs.c') diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 7c4d7bb3a56f..691314c68b59 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -2373,93 +2373,117 @@ out: static ssize_t lpfc_debugfs_dif_err_read(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) + size_t nbytes, loff_t *ppos) { struct lpfc_hba *phba = file->private_data; int kind = debugfs_get_aux_num(file); - char cbuf[32]; - uint64_t tmp = 0; + char cbuf[32] = {0}; int cnt = 0; - if (kind == writeGuard) - cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt); - else if (kind == writeApp) - cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt); - else if (kind == writeRef) - cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt); - else if (kind == readGuard) - cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt); - else if (kind == readApp) - cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt); - else if (kind == readRef) - cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt); - else if (kind == InjErrNPortID) - cnt = scnprintf(cbuf, 32, "0x%06x\n", + switch (kind) { + case writeGuard: + cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", + phba->lpfc_injerr_wgrd_cnt); + break; + case writeApp: + cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", + phba->lpfc_injerr_wapp_cnt); + break; + case writeRef: + cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", + phba->lpfc_injerr_wref_cnt); + break; + case readGuard: + cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", + phba->lpfc_injerr_rgrd_cnt); + break; + case readApp: + cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", + phba->lpfc_injerr_rapp_cnt); + break; + case readRef: + cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", + phba->lpfc_injerr_rref_cnt); + break; + case InjErrNPortID: + cnt = scnprintf(cbuf, sizeof(cbuf), "0x%06x\n", phba->lpfc_injerr_nportid); - else if (kind == InjErrWWPN) { - memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name)); - tmp = cpu_to_be64(tmp); - cnt = scnprintf(cbuf, 32, "0x%016llx\n", tmp); - } else if (kind == InjErrLBA) { - if (phba->lpfc_injerr_lba == (sector_t)(-1)) - cnt = scnprintf(cbuf, 32, "off\n"); + break; + case InjErrWWPN: + cnt = scnprintf(cbuf, sizeof(cbuf), "0x%016llx\n", + be64_to_cpu(phba->lpfc_injerr_wwpn.u.wwn_be)); + break; + case InjErrLBA: + if (phba->lpfc_injerr_lba == LPFC_INJERR_LBA_OFF) + cnt = scnprintf(cbuf, sizeof(cbuf), "off\n"); else - cnt = scnprintf(cbuf, 32, "0x%llx\n", - (uint64_t) phba->lpfc_injerr_lba); - } else - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0547 Unknown debugfs error injection entry\n"); + cnt = scnprintf(cbuf, sizeof(cbuf), "0x%llx\n", + (uint64_t)phba->lpfc_injerr_lba); + break; + default: + lpfc_log_msg(phba, KERN_WARNING, LOG_INIT, + "0547 Unknown debugfs error injection entry\n"); + break; + } return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt); } static ssize_t lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, - size_t nbytes, loff_t *ppos) + size_t nbytes, loff_t *ppos) { struct lpfc_hba *phba = file->private_data; int kind = debugfs_get_aux_num(file); - char dstbuf[33]; - uint64_t tmp = 0; - int size; + char dstbuf[33] = {0}; + unsigned long long tmp; + unsigned long size; - memset(dstbuf, 0, 33); - size = (nbytes < 32) ? nbytes : 32; + size = (nbytes < (sizeof(dstbuf) - 1)) ? nbytes : (sizeof(dstbuf) - 1); if (copy_from_user(dstbuf, buf, size)) return -EFAULT; - if (kind == InjErrLBA) { - if ((dstbuf[0] == 'o') && (dstbuf[1] == 'f') && - (dstbuf[2] == 'f')) - tmp = (uint64_t)(-1); + if (kstrtoull(dstbuf, 0, &tmp)) { + if (kind != InjErrLBA || !strstr(dstbuf, "off")) + return -EINVAL; } - if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp))) - return -EINVAL; - - if (kind == writeGuard) + switch (kind) { + case writeGuard: phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp; - else if (kind == writeApp) + break; + case writeApp: phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp; - else if (kind == writeRef) + break; + case writeRef: phba->lpfc_injerr_wref_cnt = (uint32_t)tmp; - else if (kind == readGuard) + break; + case readGuard: phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp; - else if (kind == readApp) + break; + case readApp: phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp; - else if (kind == readRef) + break; + case readRef: phba->lpfc_injerr_rref_cnt = (uint32_t)tmp; - else if (kind == InjErrLBA) - phba->lpfc_injerr_lba = (sector_t)tmp; - else if (kind == InjErrNPortID) + break; + case InjErrLBA: + if (strstr(dstbuf, "off")) + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; + else + phba->lpfc_injerr_lba = (sector_t)tmp; + break; + case InjErrNPortID: phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID); - else if (kind == InjErrWWPN) { - tmp = cpu_to_be64(tmp); - memcpy(&phba->lpfc_injerr_wwpn, &tmp, sizeof(struct lpfc_name)); - } else - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0548 Unknown debugfs error injection entry\n"); - + break; + case InjErrWWPN: + phba->lpfc_injerr_wwpn.u.wwn_be = cpu_to_be64(tmp); + break; + default: + lpfc_log_msg(phba, KERN_WARNING, LOG_INIT, + "0548 Unknown debugfs error injection entry\n"); + break; + } return nbytes; } diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 32298285ea5e..b287d39ad033 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -366,6 +366,7 @@ struct lpfc_name { } s; uint8_t wwn[8]; uint64_t name __packed __aligned(4); + __be64 wwn_be __packed __aligned(4); } u; }; -- cgit v1.2.3 From 8221b3450501c7cdc93be1eb65a6fe0dcfb4b538 Mon Sep 17 00:00:00 2001 From: Justin Tee Date: Mon, 15 Sep 2025 11:08:08 -0700 Subject: scsi: lpfc: Clean up extraneous phba dentries Because debugfs_remove recursively removes debugfs entries, the lpfc_debugfs_terminate routine is updated to remove only the parent/root debugfs directories. As such, there no longer is a need to keep track of each individual debugfs entry so clean up the unused phba dentries. Reported-by: Al Viro Closes: https://lore.kernel.org/linux-fsdevel/20250702212917.GK3406663@ZenIV/ Signed-off-by: Justin Tee Message-ID: <20250915180811.137530-12-justintee8345@gmail.com> Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 38 +--- drivers/scsi/lpfc/lpfc_debugfs.c | 476 ++++++++++----------------------------- 2 files changed, 124 insertions(+), 390 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_debugfs.c') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 588411200b00..f0e7f7ee4760 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -741,12 +741,6 @@ struct lpfc_vport { struct lpfc_vmid_priority_info vmid_priority; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - struct dentry *debug_disc_trc; - struct dentry *debug_nodelist; - struct dentry *debug_nvmestat; - struct dentry *debug_scsistat; - struct dentry *debug_ioktime; - struct dentry *debug_hdwqstat; struct dentry *vport_debugfs_root; struct lpfc_debugfs_trc *disc_trc; atomic_t disc_trc_cnt; @@ -1339,29 +1333,8 @@ struct lpfc_hba { #ifdef CONFIG_SCSI_LPFC_DEBUG_FS struct dentry *hba_debugfs_root; atomic_t debugfs_vport_count; - struct dentry *debug_multixri_pools; - struct dentry *debug_hbqinfo; - struct dentry *debug_dumpHostSlim; - struct dentry *debug_dumpHBASlim; - struct dentry *debug_InjErrLBA; /* LBA to inject errors at */ - struct dentry *debug_InjErrNPortID; /* NPortID to inject errors at */ - struct dentry *debug_InjErrWWPN; /* WWPN to inject errors at */ - struct dentry *debug_writeGuard; /* inject write guard_tag errors */ - struct dentry *debug_writeApp; /* inject write app_tag errors */ - struct dentry *debug_writeRef; /* inject write ref_tag errors */ - struct dentry *debug_readGuard; /* inject read guard_tag errors */ - struct dentry *debug_readApp; /* inject read app_tag errors */ - struct dentry *debug_readRef; /* inject read ref_tag errors */ - - struct dentry *debug_nvmeio_trc; + struct lpfc_debugfs_nvmeio_trc *nvmeio_trc; - struct dentry *debug_hdwqinfo; -#ifdef LPFC_HDWQ_LOCK_STAT - struct dentry *debug_lockstat; -#endif - struct dentry *debug_cgn_buffer; - struct dentry *debug_rx_monitor; - struct dentry *debug_ras_log; atomic_t nvmeio_trc_cnt; uint32_t nvmeio_trc_size; uint32_t nvmeio_trc_output_idx; @@ -1378,19 +1351,10 @@ struct lpfc_hba { sector_t lpfc_injerr_lba; #define LPFC_INJERR_LBA_OFF (sector_t)(-1) - struct dentry *debug_slow_ring_trc; struct lpfc_debugfs_trc *slow_ring_trc; atomic_t slow_ring_trc_cnt; /* iDiag debugfs sub-directory */ struct dentry *idiag_root; - struct dentry *idiag_pci_cfg; - struct dentry *idiag_bar_acc; - struct dentry *idiag_que_info; - struct dentry *idiag_que_acc; - struct dentry *idiag_drb_acc; - struct dentry *idiag_ctl_acc; - struct dentry *idiag_mbx_acc; - struct dentry *idiag_ext_acc; uint8_t lpfc_idiag_last_eq; #endif uint16_t nvmeio_trc_on; diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 691314c68b59..eaedbaff5a78 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -6075,6 +6075,11 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) if (!lpfc_debugfs_root) { lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); atomic_set(&lpfc_debugfs_hba_count, 0); + if (IS_ERR(lpfc_debugfs_root)) { + lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT, + "0527 Cannot create debugfs lpfc\n"); + return; + } } if (!lpfc_debugfs_start_time) lpfc_debugfs_start_time = jiffies; @@ -6085,150 +6090,96 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) pport_setup = true; phba->hba_debugfs_root = debugfs_create_dir(name, lpfc_debugfs_root); - atomic_inc(&lpfc_debugfs_hba_count); atomic_set(&phba->debugfs_vport_count, 0); + if (IS_ERR(phba->hba_debugfs_root)) { + lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT, + "0528 Cannot create debugfs %s\n", name); + return; + } + atomic_inc(&lpfc_debugfs_hba_count); /* Multi-XRI pools */ - snprintf(name, sizeof(name), "multixripools"); - phba->debug_multixri_pools = - debugfs_create_file(name, S_IFREG | 0644, - phba->hba_debugfs_root, - phba, - &lpfc_debugfs_op_multixripools); - if (IS_ERR(phba->debug_multixri_pools)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0527 Cannot create debugfs multixripools\n"); - goto debug_failed; - } + debugfs_create_file("multixripools", 0644, + phba->hba_debugfs_root, phba, + &lpfc_debugfs_op_multixripools); /* Congestion Info Buffer */ - scnprintf(name, sizeof(name), "cgn_buffer"); - phba->debug_cgn_buffer = - debugfs_create_file(name, S_IFREG | 0644, - phba->hba_debugfs_root, - phba, &lpfc_cgn_buffer_op); - if (IS_ERR(phba->debug_cgn_buffer)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "6527 Cannot create debugfs " - "cgn_buffer\n"); - goto debug_failed; - } + debugfs_create_file("cgn_buffer", 0644, phba->hba_debugfs_root, + phba, &lpfc_cgn_buffer_op); /* RX Monitor */ - scnprintf(name, sizeof(name), "rx_monitor"); - phba->debug_rx_monitor = - debugfs_create_file(name, S_IFREG | 0644, - phba->hba_debugfs_root, - phba, &lpfc_rx_monitor_op); - if (IS_ERR(phba->debug_rx_monitor)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "6528 Cannot create debugfs " - "rx_monitor\n"); - goto debug_failed; - } + debugfs_create_file("rx_monitor", 0644, phba->hba_debugfs_root, + phba, &lpfc_rx_monitor_op); /* RAS log */ - snprintf(name, sizeof(name), "ras_log"); - phba->debug_ras_log = - debugfs_create_file(name, 0644, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_ras_log); - if (IS_ERR(phba->debug_ras_log)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "6148 Cannot create debugfs" - " ras_log\n"); - goto debug_failed; - } + debugfs_create_file("ras_log", 0644, phba->hba_debugfs_root, + phba, &lpfc_debugfs_ras_log); /* Setup hbqinfo */ - snprintf(name, sizeof(name), "hbqinfo"); - phba->debug_hbqinfo = - debugfs_create_file(name, S_IFREG | 0644, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_hbqinfo); + debugfs_create_file("hbqinfo", 0644, phba->hba_debugfs_root, + phba, &lpfc_debugfs_op_hbqinfo); #ifdef LPFC_HDWQ_LOCK_STAT /* Setup lockstat */ - snprintf(name, sizeof(name), "lockstat"); - phba->debug_lockstat = - debugfs_create_file(name, S_IFREG | 0644, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_lockstat); - if (IS_ERR(phba->debug_lockstat)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "4610 Can't create debugfs lockstat\n"); - goto debug_failed; - } + debugfs_create_file("lockstat", 0644, phba->hba_debugfs_root, + phba, &lpfc_debugfs_op_lockstat); #endif - - /* Setup dumpHBASlim */ if (phba->sli_rev < LPFC_SLI_REV4) { - snprintf(name, sizeof(name), "dumpHBASlim"); - phba->debug_dumpHBASlim = - debugfs_create_file(name, - S_IFREG|S_IRUGO|S_IWUSR, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_dumpHBASlim); - } else - phba->debug_dumpHBASlim = NULL; + /* Setup dumpHBASlim */ + debugfs_create_file("dumpHBASlim", 0644, + phba->hba_debugfs_root, phba, + &lpfc_debugfs_op_dumpHBASlim); + } - /* Setup dumpHostSlim */ if (phba->sli_rev < LPFC_SLI_REV4) { - snprintf(name, sizeof(name), "dumpHostSlim"); - phba->debug_dumpHostSlim = - debugfs_create_file(name, - S_IFREG|S_IRUGO|S_IWUSR, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_dumpHostSlim); - } else - phba->debug_dumpHostSlim = NULL; + /* Setup dumpHostSlim */ + debugfs_create_file("dumpHostSlim", 0644, + phba->hba_debugfs_root, phba, + &lpfc_debugfs_op_dumpHostSlim); + } /* Setup DIF Error Injections */ - phba->debug_InjErrLBA = - debugfs_create_file_aux_num("InjErrLBA", 0644, - phba->hba_debugfs_root, - phba, InjErrLBA, &lpfc_debugfs_op_dif_err); + debugfs_create_file_aux_num("InjErrLBA", 0644, + phba->hba_debugfs_root, phba, + InjErrLBA, + &lpfc_debugfs_op_dif_err); phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; - phba->debug_InjErrNPortID = - debugfs_create_file_aux_num("InjErrNPortID", 0644, - phba->hba_debugfs_root, - phba, InjErrNPortID, &lpfc_debugfs_op_dif_err); - - phba->debug_InjErrWWPN = - debugfs_create_file_aux_num("InjErrWWPN", 0644, - phba->hba_debugfs_root, - phba, InjErrWWPN, &lpfc_debugfs_op_dif_err); - - phba->debug_writeGuard = - debugfs_create_file_aux_num("writeGuardInjErr", 0644, - phba->hba_debugfs_root, - phba, writeGuard, &lpfc_debugfs_op_dif_err); - - phba->debug_writeApp = - debugfs_create_file_aux_num("writeAppInjErr", 0644, - phba->hba_debugfs_root, - phba, writeApp, &lpfc_debugfs_op_dif_err); - - phba->debug_writeRef = - debugfs_create_file_aux_num("writeRefInjErr", 0644, - phba->hba_debugfs_root, - phba, writeRef, &lpfc_debugfs_op_dif_err); - - phba->debug_readGuard = - debugfs_create_file_aux_num("readGuardInjErr", 0644, - phba->hba_debugfs_root, - phba, readGuard, &lpfc_debugfs_op_dif_err); - - phba->debug_readApp = - debugfs_create_file_aux_num("readAppInjErr", 0644, - phba->hba_debugfs_root, - phba, readApp, &lpfc_debugfs_op_dif_err); - - phba->debug_readRef = - debugfs_create_file_aux_num("readRefInjErr", 0644, - phba->hba_debugfs_root, - phba, readRef, &lpfc_debugfs_op_dif_err); + debugfs_create_file_aux_num("InjErrNPortID", 0644, + phba->hba_debugfs_root, phba, + InjErrNPortID, + &lpfc_debugfs_op_dif_err); + + debugfs_create_file_aux_num("InjErrWWPN", 0644, + phba->hba_debugfs_root, phba, + InjErrWWPN, + &lpfc_debugfs_op_dif_err); + + debugfs_create_file_aux_num("writeGuardInjErr", 0644, + phba->hba_debugfs_root, phba, + writeGuard, + &lpfc_debugfs_op_dif_err); + + debugfs_create_file_aux_num("writeAppInjErr", 0644, + phba->hba_debugfs_root, phba, + writeApp, &lpfc_debugfs_op_dif_err); + + debugfs_create_file_aux_num("writeRefInjErr", 0644, + phba->hba_debugfs_root, phba, + writeRef, &lpfc_debugfs_op_dif_err); + + debugfs_create_file_aux_num("readGuardInjErr", 0644, + phba->hba_debugfs_root, phba, + readGuard, + &lpfc_debugfs_op_dif_err); + + debugfs_create_file_aux_num("readAppInjErr", 0644, + phba->hba_debugfs_root, phba, + readApp, &lpfc_debugfs_op_dif_err); + + debugfs_create_file_aux_num("readRefInjErr", 0644, + phba->hba_debugfs_root, phba, + readRef, &lpfc_debugfs_op_dif_err); /* Setup slow ring trace */ if (lpfc_debugfs_max_slow_ring_trc) { @@ -6248,11 +6199,9 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) } } - snprintf(name, sizeof(name), "slow_ring_trace"); - phba->debug_slow_ring_trc = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_slow_ring_trc); + debugfs_create_file("slow_ring_trace", 0644, + phba->hba_debugfs_root, phba, + &lpfc_debugfs_op_slow_ring_trc); if (!phba->slow_ring_trc) { phba->slow_ring_trc = kcalloc( lpfc_debugfs_max_slow_ring_trc, @@ -6262,16 +6211,13 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0416 Cannot create debugfs " "slow_ring buffer\n"); - goto debug_failed; + goto out; } atomic_set(&phba->slow_ring_trc_cnt, 0); } - snprintf(name, sizeof(name), "nvmeio_trc"); - phba->debug_nvmeio_trc = - debugfs_create_file(name, 0644, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_nvmeio_trc); + debugfs_create_file("nvmeio_trc", 0644, phba->hba_debugfs_root, + phba, &lpfc_debugfs_op_nvmeio_trc); atomic_set(&phba->nvmeio_trc_cnt, 0); if (lpfc_debugfs_max_nvmeio_trc) { @@ -6317,6 +6263,11 @@ nvmeio_off: if (!vport->vport_debugfs_root) { vport->vport_debugfs_root = debugfs_create_dir(name, phba->hba_debugfs_root); + if (IS_ERR(vport->vport_debugfs_root)) { + lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT, + "0529 Cannot create debugfs %s\n", name); + return; + } atomic_inc(&phba->debugfs_vport_count); } @@ -6344,54 +6295,27 @@ nvmeio_off: lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0418 Cannot create debugfs disc trace " "buffer\n"); - goto debug_failed; + goto out; } atomic_set(&vport->disc_trc_cnt, 0); - snprintf(name, sizeof(name), "discovery_trace"); - vport->debug_disc_trc = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - vport->vport_debugfs_root, - vport, &lpfc_debugfs_op_disc_trc); - snprintf(name, sizeof(name), "nodelist"); - vport->debug_nodelist = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - vport->vport_debugfs_root, - vport, &lpfc_debugfs_op_nodelist); - - snprintf(name, sizeof(name), "nvmestat"); - vport->debug_nvmestat = - debugfs_create_file(name, 0644, - vport->vport_debugfs_root, - vport, &lpfc_debugfs_op_nvmestat); - - snprintf(name, sizeof(name), "scsistat"); - vport->debug_scsistat = - debugfs_create_file(name, 0644, - vport->vport_debugfs_root, - vport, &lpfc_debugfs_op_scsistat); - if (IS_ERR(vport->debug_scsistat)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "4611 Cannot create debugfs scsistat\n"); - goto debug_failed; - } + debugfs_create_file("discovery_trace", 0644, vport->vport_debugfs_root, + vport, &lpfc_debugfs_op_disc_trc); - snprintf(name, sizeof(name), "ioktime"); - vport->debug_ioktime = - debugfs_create_file(name, 0644, - vport->vport_debugfs_root, - vport, &lpfc_debugfs_op_ioktime); - if (IS_ERR(vport->debug_ioktime)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0815 Cannot create debugfs ioktime\n"); - goto debug_failed; - } + debugfs_create_file("nodelist", 0644, vport->vport_debugfs_root, vport, + &lpfc_debugfs_op_nodelist); + + debugfs_create_file("nvmestat", 0644, vport->vport_debugfs_root, vport, + &lpfc_debugfs_op_nvmestat); - snprintf(name, sizeof(name), "hdwqstat"); - vport->debug_hdwqstat = - debugfs_create_file(name, 0644, - vport->vport_debugfs_root, - vport, &lpfc_debugfs_op_hdwqstat); + debugfs_create_file("scsistat", 0644, vport->vport_debugfs_root, vport, + &lpfc_debugfs_op_scsistat); + + debugfs_create_file("ioktime", 0644, vport->vport_debugfs_root, vport, + &lpfc_debugfs_op_ioktime); + + debugfs_create_file("hdwqstat", 0644, vport->vport_debugfs_root, vport, + &lpfc_debugfs_op_hdwqstat); /* * The following section is for additional directories/files for the @@ -6399,93 +6323,58 @@ nvmeio_off: */ if (!pport_setup) - goto debug_failed; + return; /* * iDiag debugfs root entry points for SLI4 device only */ if (phba->sli_rev < LPFC_SLI_REV4) - goto debug_failed; + return; - snprintf(name, sizeof(name), "iDiag"); if (!phba->idiag_root) { phba->idiag_root = - debugfs_create_dir(name, phba->hba_debugfs_root); + debugfs_create_dir("iDiag", phba->hba_debugfs_root); /* Initialize iDiag data structure */ memset(&idiag, 0, sizeof(idiag)); } /* iDiag read PCI config space */ - snprintf(name, sizeof(name), "pciCfg"); - if (!phba->idiag_pci_cfg) { - phba->idiag_pci_cfg = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->idiag_root, phba, &lpfc_idiag_op_pciCfg); - idiag.offset.last_rd = 0; - } + debugfs_create_file("pciCfg", 0644, phba->idiag_root, phba, + &lpfc_idiag_op_pciCfg); + idiag.offset.last_rd = 0; /* iDiag PCI BAR access */ - snprintf(name, sizeof(name), "barAcc"); - if (!phba->idiag_bar_acc) { - phba->idiag_bar_acc = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->idiag_root, phba, &lpfc_idiag_op_barAcc); - idiag.offset.last_rd = 0; - } + debugfs_create_file("barAcc", 0644, phba->idiag_root, phba, + &lpfc_idiag_op_barAcc); + idiag.offset.last_rd = 0; /* iDiag get PCI function queue information */ - snprintf(name, sizeof(name), "queInfo"); - if (!phba->idiag_que_info) { - phba->idiag_que_info = - debugfs_create_file(name, S_IFREG|S_IRUGO, - phba->idiag_root, phba, &lpfc_idiag_op_queInfo); - } + debugfs_create_file("queInfo", 0444, phba->idiag_root, phba, + &lpfc_idiag_op_queInfo); /* iDiag access PCI function queue */ - snprintf(name, sizeof(name), "queAcc"); - if (!phba->idiag_que_acc) { - phba->idiag_que_acc = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->idiag_root, phba, &lpfc_idiag_op_queAcc); - } + debugfs_create_file("queAcc", 0644, phba->idiag_root, phba, + &lpfc_idiag_op_queAcc); /* iDiag access PCI function doorbell registers */ - snprintf(name, sizeof(name), "drbAcc"); - if (!phba->idiag_drb_acc) { - phba->idiag_drb_acc = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->idiag_root, phba, &lpfc_idiag_op_drbAcc); - } + debugfs_create_file("drbAcc", 0644, phba->idiag_root, phba, + &lpfc_idiag_op_drbAcc); /* iDiag access PCI function control registers */ - snprintf(name, sizeof(name), "ctlAcc"); - if (!phba->idiag_ctl_acc) { - phba->idiag_ctl_acc = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc); - } + debugfs_create_file("ctlAcc", 0644, phba->idiag_root, phba, + &lpfc_idiag_op_ctlAcc); /* iDiag access mbox commands */ - snprintf(name, sizeof(name), "mbxAcc"); - if (!phba->idiag_mbx_acc) { - phba->idiag_mbx_acc = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc); - } + debugfs_create_file("mbxAcc", 0644, phba->idiag_root, phba, + &lpfc_idiag_op_mbxAcc); /* iDiag extents access commands */ if (phba->sli4_hba.extents_in_use) { - snprintf(name, sizeof(name), "extAcc"); - if (!phba->idiag_ext_acc) { - phba->idiag_ext_acc = - debugfs_create_file(name, - S_IFREG|S_IRUGO|S_IWUSR, - phba->idiag_root, phba, - &lpfc_idiag_op_extAcc); - } + debugfs_create_file("extAcc", 0644, phba->idiag_root, phba, + &lpfc_idiag_op_extAcc); } - -debug_failed: +out: + /* alloc'ed items are kfree'd in lpfc_debugfs_terminate */ return; #endif } @@ -6510,24 +6399,6 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) kfree(vport->disc_trc); vport->disc_trc = NULL; - debugfs_remove(vport->debug_disc_trc); /* discovery_trace */ - vport->debug_disc_trc = NULL; - - debugfs_remove(vport->debug_nodelist); /* nodelist */ - vport->debug_nodelist = NULL; - - debugfs_remove(vport->debug_nvmestat); /* nvmestat */ - vport->debug_nvmestat = NULL; - - debugfs_remove(vport->debug_scsistat); /* scsistat */ - vport->debug_scsistat = NULL; - - debugfs_remove(vport->debug_ioktime); /* ioktime */ - vport->debug_ioktime = NULL; - - debugfs_remove(vport->debug_hdwqstat); /* hdwqstat */ - vport->debug_hdwqstat = NULL; - if (vport->vport_debugfs_root) { debugfs_remove(vport->vport_debugfs_root); /* vportX */ vport->vport_debugfs_root = NULL; @@ -6535,113 +6406,12 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) } if (atomic_read(&phba->debugfs_vport_count) == 0) { - - debugfs_remove(phba->debug_multixri_pools); /* multixripools*/ - phba->debug_multixri_pools = NULL; - - debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */ - phba->debug_hbqinfo = NULL; - - debugfs_remove(phba->debug_cgn_buffer); - phba->debug_cgn_buffer = NULL; - - debugfs_remove(phba->debug_rx_monitor); - phba->debug_rx_monitor = NULL; - - debugfs_remove(phba->debug_ras_log); - phba->debug_ras_log = NULL; - -#ifdef LPFC_HDWQ_LOCK_STAT - debugfs_remove(phba->debug_lockstat); /* lockstat */ - phba->debug_lockstat = NULL; -#endif - debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */ - phba->debug_dumpHBASlim = NULL; - - debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */ - phba->debug_dumpHostSlim = NULL; - - debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */ - phba->debug_InjErrLBA = NULL; - - debugfs_remove(phba->debug_InjErrNPortID); - phba->debug_InjErrNPortID = NULL; - - debugfs_remove(phba->debug_InjErrWWPN); /* InjErrWWPN */ - phba->debug_InjErrWWPN = NULL; - - debugfs_remove(phba->debug_writeGuard); /* writeGuard */ - phba->debug_writeGuard = NULL; - - debugfs_remove(phba->debug_writeApp); /* writeApp */ - phba->debug_writeApp = NULL; - - debugfs_remove(phba->debug_writeRef); /* writeRef */ - phba->debug_writeRef = NULL; - - debugfs_remove(phba->debug_readGuard); /* readGuard */ - phba->debug_readGuard = NULL; - - debugfs_remove(phba->debug_readApp); /* readApp */ - phba->debug_readApp = NULL; - - debugfs_remove(phba->debug_readRef); /* readRef */ - phba->debug_readRef = NULL; - kfree(phba->slow_ring_trc); phba->slow_ring_trc = NULL; - /* slow_ring_trace */ - debugfs_remove(phba->debug_slow_ring_trc); - phba->debug_slow_ring_trc = NULL; - - debugfs_remove(phba->debug_nvmeio_trc); - phba->debug_nvmeio_trc = NULL; - kfree(phba->nvmeio_trc); phba->nvmeio_trc = NULL; - /* - * iDiag release - */ - if (phba->sli_rev == LPFC_SLI_REV4) { - /* iDiag extAcc */ - debugfs_remove(phba->idiag_ext_acc); - phba->idiag_ext_acc = NULL; - - /* iDiag mbxAcc */ - debugfs_remove(phba->idiag_mbx_acc); - phba->idiag_mbx_acc = NULL; - - /* iDiag ctlAcc */ - debugfs_remove(phba->idiag_ctl_acc); - phba->idiag_ctl_acc = NULL; - - /* iDiag drbAcc */ - debugfs_remove(phba->idiag_drb_acc); - phba->idiag_drb_acc = NULL; - - /* iDiag queAcc */ - debugfs_remove(phba->idiag_que_acc); - phba->idiag_que_acc = NULL; - - /* iDiag queInfo */ - debugfs_remove(phba->idiag_que_info); - phba->idiag_que_info = NULL; - - /* iDiag barAcc */ - debugfs_remove(phba->idiag_bar_acc); - phba->idiag_bar_acc = NULL; - - /* iDiag pciCfg */ - debugfs_remove(phba->idiag_pci_cfg); - phba->idiag_pci_cfg = NULL; - - /* Finally remove the iDiag debugfs root */ - debugfs_remove(phba->idiag_root); - phba->idiag_root = NULL; - } - if (phba->hba_debugfs_root) { debugfs_remove(phba->hba_debugfs_root); /* fnX */ phba->hba_debugfs_root = NULL; -- cgit v1.2.3 From a045ae21ce3e3411ac38ff2f9051792585f444d7 Mon Sep 17 00:00:00 2001 From: Justin Tee Date: Mon, 15 Sep 2025 11:08:09 -0700 Subject: scsi: lpfc: Convert debugfs directory counts from atomic to unsigned int Atomicity is not necessary for debugfs directory accounting because vport deletion and creation is already serialized. Creation has always been serialized through sysfs. Deletion is serialized via walking the lpfc_create_vport_work_array and calling fc_vport_terminate one-by-one for each NPIV port. Reported-by: Al Viro Closes: https://lore.kernel.org/linux-fsdevel/20250702212917.GK3406663@ZenIV/ Signed-off-by: Justin Tee Message-ID: <20250915180811.137530-13-justintee8345@gmail.com> Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 2 +- drivers/scsi/lpfc/lpfc_debugfs.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_debugfs.c') diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index f0e7f7ee4760..8d9870764a8e 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1332,7 +1332,7 @@ struct lpfc_hba { unsigned long last_ramp_down_time; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS struct dentry *hba_debugfs_root; - atomic_t debugfs_vport_count; + unsigned int debugfs_vport_count; struct lpfc_debugfs_nvmeio_trc *nvmeio_trc; atomic_t nvmeio_trc_cnt; diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index eaedbaff5a78..92b5b2dbe847 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -5752,7 +5752,7 @@ static const struct file_operations lpfc_debugfs_op_slow_ring_trc = { }; static struct dentry *lpfc_debugfs_root = NULL; -static atomic_t lpfc_debugfs_hba_count; +static unsigned int lpfc_debugfs_hba_count; /* * File operations for the iDiag debugfs @@ -6074,7 +6074,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) /* Setup lpfc root directory */ if (!lpfc_debugfs_root) { lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); - atomic_set(&lpfc_debugfs_hba_count, 0); + lpfc_debugfs_hba_count = 0; if (IS_ERR(lpfc_debugfs_root)) { lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT, "0527 Cannot create debugfs lpfc\n"); @@ -6090,13 +6090,13 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) pport_setup = true; phba->hba_debugfs_root = debugfs_create_dir(name, lpfc_debugfs_root); - atomic_set(&phba->debugfs_vport_count, 0); + phba->debugfs_vport_count = 0; if (IS_ERR(phba->hba_debugfs_root)) { lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT, "0528 Cannot create debugfs %s\n", name); return; } - atomic_inc(&lpfc_debugfs_hba_count); + lpfc_debugfs_hba_count++; /* Multi-XRI pools */ debugfs_create_file("multixripools", 0644, @@ -6268,7 +6268,7 @@ nvmeio_off: "0529 Cannot create debugfs %s\n", name); return; } - atomic_inc(&phba->debugfs_vport_count); + phba->debugfs_vport_count++; } if (lpfc_debugfs_max_disc_trc) { @@ -6402,10 +6402,10 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) if (vport->vport_debugfs_root) { debugfs_remove(vport->vport_debugfs_root); /* vportX */ vport->vport_debugfs_root = NULL; - atomic_dec(&phba->debugfs_vport_count); + phba->debugfs_vport_count--; } - if (atomic_read(&phba->debugfs_vport_count) == 0) { + if (!phba->debugfs_vport_count) { kfree(phba->slow_ring_trc); phba->slow_ring_trc = NULL; @@ -6415,10 +6415,10 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) if (phba->hba_debugfs_root) { debugfs_remove(phba->hba_debugfs_root); /* fnX */ phba->hba_debugfs_root = NULL; - atomic_dec(&lpfc_debugfs_hba_count); + lpfc_debugfs_hba_count--; } - if (atomic_read(&lpfc_debugfs_hba_count) == 0) { + if (!lpfc_debugfs_hba_count) { debugfs_remove(lpfc_debugfs_root); /* lpfc */ lpfc_debugfs_root = NULL; } -- cgit v1.2.3