diff --git a/patches.suse/scsi-lpfc-Use-a-dedicated-lock-for-ras_fwlog-state.patch b/patches.suse/scsi-lpfc-Use-a-dedicated-lock-for-ras_fwlog-state.patch new file mode 100644 index 0000000..a24f81e --- /dev/null +++ b/patches.suse/scsi-lpfc-Use-a-dedicated-lock-for-ras_fwlog-state.patch @@ -0,0 +1,221 @@ +From: Justin Tee +Date: Tue, 5 Mar 2024 12:04:58 -0800 +Subject: scsi: lpfc: Use a dedicated lock for ras_fwlog state +Patch-mainline: Queued in subsystem maintainer repository +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git +Git-commit: f733a76ea0a9a84aee4ac41b81fad4d610ecbd8e +References: bsc#1221777 + +To reduce usage of and contention for hbalock, a separate dedicated lock is +used to protect ras_fwlog state. + +Signed-off-by: Justin Tee +Link: https://lore.kernel.org/r/20240305200503.57317-8-justintee8345@gmail.com +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc.h | 1 + + drivers/scsi/lpfc/lpfc_attr.c | 4 ++-- + drivers/scsi/lpfc/lpfc_bsg.c | 20 ++++++++++---------- + drivers/scsi/lpfc/lpfc_debugfs.c | 12 ++++++------ + drivers/scsi/lpfc/lpfc_init.c | 3 +++ + drivers/scsi/lpfc/lpfc_sli.c | 20 ++++++++++---------- + 6 files changed, 32 insertions(+), 28 deletions(-) + +--- a/drivers/scsi/lpfc/lpfc_attr.c ++++ b/drivers/scsi/lpfc/lpfc_attr.c +@@ -5865,9 +5865,9 @@ lpfc_ras_fwlog_buffsize_set(struct lpfc_ + if (phba->cfg_ras_fwlog_func != PCI_FUNC(phba->pcidev->devfn)) + return -EINVAL; + +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + state = phba->ras_fwlog.state; +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + + if (state == REG_INPROGRESS) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "6147 RAS Logging " +--- a/drivers/scsi/lpfc/lpfc_bsg.c ++++ b/drivers/scsi/lpfc/lpfc_bsg.c +@@ -5070,12 +5070,12 @@ lpfc_bsg_get_ras_config(struct bsg_job * + bsg_reply->reply_data.vendor_reply.vendor_rsp; + + /* Current logging state */ +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + if (ras_fwlog->state == ACTIVE) + ras_reply->state = LPFC_RASLOG_STATE_RUNNING; + else + ras_reply->state = LPFC_RASLOG_STATE_STOPPED; +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + + ras_reply->log_level = phba->ras_fwlog.fw_loglevel; + ras_reply->log_buff_sz = phba->cfg_ras_fwlog_buffsize; +@@ -5132,13 +5132,13 @@ lpfc_bsg_set_ras_config(struct bsg_job * + + if (action == LPFC_RASACTION_STOP_LOGGING) { + /* Check if already disabled */ +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + if (ras_fwlog->state != ACTIVE) { +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + rc = -ESRCH; + goto ras_job_error; + } +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + + /* Disable logging */ + lpfc_ras_stop_fwlog(phba); +@@ -5149,10 +5149,10 @@ lpfc_bsg_set_ras_config(struct bsg_job * + * FW-logging with new log-level. Return status + * "Logging already Running" to caller. + **/ +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + if (ras_fwlog->state != INACTIVE) + action_status = -EINPROGRESS; +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + + /* Enable logging */ + rc = lpfc_sli4_ras_fwlog_init(phba, log_level, +@@ -5268,13 +5268,13 @@ lpfc_bsg_get_ras_fwlog(struct bsg_job *j + goto ras_job_error; + + /* Logging to be stopped before reading */ +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + if (ras_fwlog->state == ACTIVE) { +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + rc = -EINPROGRESS; + goto ras_job_error; + } +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + + if (job->request_len < + sizeof(struct fc_bsg_request) + +--- a/drivers/scsi/lpfc/lpfc_debugfs.c ++++ b/drivers/scsi/lpfc/lpfc_debugfs.c +@@ -2194,12 +2194,12 @@ static int lpfc_debugfs_ras_log_data(str + + memset(buffer, 0, size); + +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + if (phba->ras_fwlog.state != ACTIVE) { +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + return -EINVAL; + } +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + + list_for_each_entry_safe(dmabuf, next, + &phba->ras_fwlog.fwlog_buff_list, list) { +@@ -2250,13 +2250,13 @@ lpfc_debugfs_ras_log_open(struct inode * + int size; + int rc = -ENOMEM; + +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + if (phba->ras_fwlog.state != ACTIVE) { +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + rc = -EINVAL; + goto out; + } +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + + if (check_mul_overflow(LPFC_RAS_MIN_BUFF_POST_SIZE, + (int)phba->cfg_ras_fwlog_buffsize, &size)) +--- a/drivers/scsi/lpfc/lpfc.h ++++ b/drivers/scsi/lpfc/lpfc.h +@@ -1437,6 +1437,7 @@ struct lpfc_hba { + struct timer_list inactive_vmid_poll; + + /* RAS Support */ ++ spinlock_t ras_fwlog_lock; /* do not take while holding another lock */ + struct lpfc_ras_fwlog ras_fwlog; + + uint32_t iocb_cnt; +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -7705,6 +7705,9 @@ lpfc_setup_driver_resource_phase1(struct + "NVME" : " "), + (phba->nvmet_support ? "NVMET" : " ")); + ++ /* ras_fwlog state */ ++ spin_lock_init(&phba->ras_fwlog_lock); ++ + /* Initialize the IO buffer list used by driver for SLI3 SCSI */ + spin_lock_init(&phba->scsi_buf_list_get_lock); + INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_get); +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -6849,9 +6849,9 @@ lpfc_ras_stop_fwlog(struct lpfc_hba *phb + { + struct lpfc_ras_fwlog *ras_fwlog = &phba->ras_fwlog; + +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + ras_fwlog->state = INACTIVE; +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + + /* Disable FW logging to host memory */ + writel(LPFC_CTL_PDEV_CTL_DDL_RAS, +@@ -6894,9 +6894,9 @@ lpfc_sli4_ras_dma_free(struct lpfc_hba * + ras_fwlog->lwpd.virt = NULL; + } + +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + ras_fwlog->state = INACTIVE; +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + } + + /** +@@ -6998,9 +6998,9 @@ lpfc_sli4_ras_mbox_cmpl(struct lpfc_hba + goto disable_ras; + } + +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + ras_fwlog->state = ACTIVE; +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + mempool_free(pmb, phba->mbox_mem_pool); + + return; +@@ -7032,9 +7032,9 @@ lpfc_sli4_ras_fwlog_init(struct lpfc_hba + uint32_t len = 0, fwlog_buffsize, fwlog_entry_count; + int rc = 0; + +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + ras_fwlog->state = INACTIVE; +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + + fwlog_buffsize = (LPFC_RAS_MIN_BUFF_POST_SIZE * + phba->cfg_ras_fwlog_buffsize); +@@ -7095,9 +7095,9 @@ lpfc_sli4_ras_fwlog_init(struct lpfc_hba + mbx_fwlog->u.request.lwpd.addr_lo = putPaddrLow(ras_fwlog->lwpd.phys); + mbx_fwlog->u.request.lwpd.addr_hi = putPaddrHigh(ras_fwlog->lwpd.phys); + +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irq(&phba->ras_fwlog_lock); + ras_fwlog->state = REG_INPROGRESS; +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irq(&phba->ras_fwlog_lock); + mbox->vport = phba->pport; + mbox->mbox_cmpl = lpfc_sli4_ras_mbox_cmpl; + diff --git a/series.conf b/series.conf index 31c9084..f83d4ae 100644 --- a/series.conf +++ b/series.conf @@ -20074,6 +20074,7 @@ patches.suse/scsi-lpfc-Update-lpfc_ramp_down_queue_handler-logic.patch patches.suse/scsi-lpfc-Replace-hbalock-with-ndlp-lock-in-lpfc_nvm.patch patches.suse/scsi-lpfc-Release-hbalock-before-calling-lpfc_worker.patch + patches.suse/scsi-lpfc-Use-a-dedicated-lock-for-ras_fwlog-state.patch ######################################################## # end of sorted patches