]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: lpfc: Use a dedicated lock for ras_fwlog state
authorJustin Tee <justin.tee@broadcom.com>
Tue, 5 Mar 2024 20:04:58 +0000 (12:04 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 May 2024 10:14:37 +0000 (12:14 +0200)
[ Upstream commit f733a76ea0a9a84aee4ac41b81fad4d610ecbd8e ]

To reduce usage of and contention for hbalock, a separate dedicated lock is
used to protect ras_fwlog state.

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20240305200503.57317-8-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_bsg.c
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c

index be016732ab2eafe1e715ffc1fab666f3a8ce0f3e..9670cb2bf198e43d23f2b00250505820d7c9a081 100644 (file)
@@ -1429,6 +1429,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;
index d3a5d6ecdf7d2a23d0ee94bc83d5ffc295947c82..6f97a04171c442e6a45efa433304f57f518bd29e 100644 (file)
@@ -5864,9 +5864,9 @@ lpfc_ras_fwlog_buffsize_set(struct lpfc_hba  *phba, uint val)
        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 "
index 2919579fa0846c1dcf3612f6f3d26959e9000d5a..c305d16cfae9aa721833c3f8bdb38eee1c2fb145 100644 (file)
@@ -5070,12 +5070,12 @@ lpfc_bsg_get_ras_config(struct bsg_job *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 *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 *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 *job)
                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) +
index ea9b42225e629dd5840e29c8bce622aef7736444..20662b4f339eb3b25d968f8044950a79db6286f5 100644 (file)
@@ -2196,12 +2196,12 @@ static int lpfc_debugfs_ras_log_data(struct lpfc_hba *phba,
 
        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) {
@@ -2252,13 +2252,13 @@ lpfc_debugfs_ras_log_open(struct inode *inode, struct file *file)
        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,
                               phba->cfg_ras_fwlog_buffsize, &size))
index 7820a1a7aa6d10161e2cd2bec4344743f38a1f69..858ca395c0bf0970165d732475b4ea71a944a985 100644 (file)
@@ -7698,6 +7698,9 @@ lpfc_setup_driver_resource_phase1(struct lpfc_hba *phba)
                                "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);
index c00b945947b1d2e77968dbef4c86ffd3be91e05d..e1821072552a5c0b5cdd41099ca0540063b55c40 100644 (file)
@@ -6849,9 +6849,9 @@ lpfc_ras_stop_fwlog(struct lpfc_hba *phba)
 {
        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 *phba)
                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 *phba, LPFC_MBOXQ_t *pmb)
                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 *phba,
        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 *phba,
        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;