1 From 4ee9c190dcec49c0f17dcb2344f805e07ed96de7 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Tue, 5 Mar 2024 12:04:58 -0800
4 Subject: scsi: lpfc: Use a dedicated lock for ras_fwlog state
6 From: Justin Tee <justin.tee@broadcom.com>
8 [ Upstream commit f733a76ea0a9a84aee4ac41b81fad4d610ecbd8e ]
10 To reduce usage of and contention for hbalock, a separate dedicated lock is
11 used to protect ras_fwlog state.
13 Signed-off-by: Justin Tee <justin.tee@broadcom.com>
14 Link: https://lore.kernel.org/r/20240305200503.57317-8-justintee8345@gmail.com
15 Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
16 Signed-off-by: Sasha Levin <sashal@kernel.org>
18 drivers/scsi/lpfc/lpfc.h | 1 +
19 drivers/scsi/lpfc/lpfc_attr.c | 4 ++--
20 drivers/scsi/lpfc/lpfc_bsg.c | 20 ++++++++++----------
21 drivers/scsi/lpfc/lpfc_debugfs.c | 12 ++++++------
22 drivers/scsi/lpfc/lpfc_init.c | 3 +++
23 drivers/scsi/lpfc/lpfc_sli.c | 20 ++++++++++----------
24 6 files changed, 32 insertions(+), 28 deletions(-)
26 diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
27 index be016732ab2ea..9670cb2bf198e 100644
28 --- a/drivers/scsi/lpfc/lpfc.h
29 +++ b/drivers/scsi/lpfc/lpfc.h
30 @@ -1429,6 +1429,7 @@ struct lpfc_hba {
31 struct timer_list inactive_vmid_poll;
34 + spinlock_t ras_fwlog_lock; /* do not take while holding another lock */
35 struct lpfc_ras_fwlog ras_fwlog;
38 diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
39 index b1c9107d34083..79b45ea5fdb5e 100644
40 --- a/drivers/scsi/lpfc/lpfc_attr.c
41 +++ b/drivers/scsi/lpfc/lpfc_attr.c
42 @@ -5864,9 +5864,9 @@ lpfc_ras_fwlog_buffsize_set(struct lpfc_hba *phba, uint val)
43 if (phba->cfg_ras_fwlog_func != PCI_FUNC(phba->pcidev->devfn))
46 - spin_lock_irq(&phba->hbalock);
47 + spin_lock_irq(&phba->ras_fwlog_lock);
48 state = phba->ras_fwlog.state;
49 - spin_unlock_irq(&phba->hbalock);
50 + spin_unlock_irq(&phba->ras_fwlog_lock);
52 if (state == REG_INPROGRESS) {
53 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "6147 RAS Logging "
54 diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
55 index 2919579fa0846..c305d16cfae9a 100644
56 --- a/drivers/scsi/lpfc/lpfc_bsg.c
57 +++ b/drivers/scsi/lpfc/lpfc_bsg.c
58 @@ -5070,12 +5070,12 @@ lpfc_bsg_get_ras_config(struct bsg_job *job)
59 bsg_reply->reply_data.vendor_reply.vendor_rsp;
61 /* Current logging state */
62 - spin_lock_irq(&phba->hbalock);
63 + spin_lock_irq(&phba->ras_fwlog_lock);
64 if (ras_fwlog->state == ACTIVE)
65 ras_reply->state = LPFC_RASLOG_STATE_RUNNING;
67 ras_reply->state = LPFC_RASLOG_STATE_STOPPED;
68 - spin_unlock_irq(&phba->hbalock);
69 + spin_unlock_irq(&phba->ras_fwlog_lock);
71 ras_reply->log_level = phba->ras_fwlog.fw_loglevel;
72 ras_reply->log_buff_sz = phba->cfg_ras_fwlog_buffsize;
73 @@ -5132,13 +5132,13 @@ lpfc_bsg_set_ras_config(struct bsg_job *job)
75 if (action == LPFC_RASACTION_STOP_LOGGING) {
76 /* Check if already disabled */
77 - spin_lock_irq(&phba->hbalock);
78 + spin_lock_irq(&phba->ras_fwlog_lock);
79 if (ras_fwlog->state != ACTIVE) {
80 - spin_unlock_irq(&phba->hbalock);
81 + spin_unlock_irq(&phba->ras_fwlog_lock);
85 - spin_unlock_irq(&phba->hbalock);
86 + spin_unlock_irq(&phba->ras_fwlog_lock);
89 lpfc_ras_stop_fwlog(phba);
90 @@ -5149,10 +5149,10 @@ lpfc_bsg_set_ras_config(struct bsg_job *job)
91 * FW-logging with new log-level. Return status
92 * "Logging already Running" to caller.
94 - spin_lock_irq(&phba->hbalock);
95 + spin_lock_irq(&phba->ras_fwlog_lock);
96 if (ras_fwlog->state != INACTIVE)
97 action_status = -EINPROGRESS;
98 - spin_unlock_irq(&phba->hbalock);
99 + spin_unlock_irq(&phba->ras_fwlog_lock);
102 rc = lpfc_sli4_ras_fwlog_init(phba, log_level,
103 @@ -5268,13 +5268,13 @@ lpfc_bsg_get_ras_fwlog(struct bsg_job *job)
106 /* Logging to be stopped before reading */
107 - spin_lock_irq(&phba->hbalock);
108 + spin_lock_irq(&phba->ras_fwlog_lock);
109 if (ras_fwlog->state == ACTIVE) {
110 - spin_unlock_irq(&phba->hbalock);
111 + spin_unlock_irq(&phba->ras_fwlog_lock);
115 - spin_unlock_irq(&phba->hbalock);
116 + spin_unlock_irq(&phba->ras_fwlog_lock);
118 if (job->request_len <
119 sizeof(struct fc_bsg_request) +
120 diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
121 index ea9b42225e629..20662b4f339eb 100644
122 --- a/drivers/scsi/lpfc/lpfc_debugfs.c
123 +++ b/drivers/scsi/lpfc/lpfc_debugfs.c
124 @@ -2196,12 +2196,12 @@ static int lpfc_debugfs_ras_log_data(struct lpfc_hba *phba,
126 memset(buffer, 0, size);
128 - spin_lock_irq(&phba->hbalock);
129 + spin_lock_irq(&phba->ras_fwlog_lock);
130 if (phba->ras_fwlog.state != ACTIVE) {
131 - spin_unlock_irq(&phba->hbalock);
132 + spin_unlock_irq(&phba->ras_fwlog_lock);
135 - spin_unlock_irq(&phba->hbalock);
136 + spin_unlock_irq(&phba->ras_fwlog_lock);
138 list_for_each_entry_safe(dmabuf, next,
139 &phba->ras_fwlog.fwlog_buff_list, list) {
140 @@ -2252,13 +2252,13 @@ lpfc_debugfs_ras_log_open(struct inode *inode, struct file *file)
144 - spin_lock_irq(&phba->hbalock);
145 + spin_lock_irq(&phba->ras_fwlog_lock);
146 if (phba->ras_fwlog.state != ACTIVE) {
147 - spin_unlock_irq(&phba->hbalock);
148 + spin_unlock_irq(&phba->ras_fwlog_lock);
152 - spin_unlock_irq(&phba->hbalock);
153 + spin_unlock_irq(&phba->ras_fwlog_lock);
155 if (check_mul_overflow(LPFC_RAS_MIN_BUFF_POST_SIZE,
156 phba->cfg_ras_fwlog_buffsize, &size))
157 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
158 index 76c883cc66ed6..416816d74ea1c 100644
159 --- a/drivers/scsi/lpfc/lpfc_init.c
160 +++ b/drivers/scsi/lpfc/lpfc_init.c
161 @@ -7698,6 +7698,9 @@ lpfc_setup_driver_resource_phase1(struct lpfc_hba *phba)
163 (phba->nvmet_support ? "NVMET" : " "));
165 + /* ras_fwlog state */
166 + spin_lock_init(&phba->ras_fwlog_lock);
168 /* Initialize the IO buffer list used by driver for SLI3 SCSI */
169 spin_lock_init(&phba->scsi_buf_list_get_lock);
170 INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_get);
171 diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
172 index 9dab33686a931..5af669b930193 100644
173 --- a/drivers/scsi/lpfc/lpfc_sli.c
174 +++ b/drivers/scsi/lpfc/lpfc_sli.c
175 @@ -6844,9 +6844,9 @@ lpfc_ras_stop_fwlog(struct lpfc_hba *phba)
177 struct lpfc_ras_fwlog *ras_fwlog = &phba->ras_fwlog;
179 - spin_lock_irq(&phba->hbalock);
180 + spin_lock_irq(&phba->ras_fwlog_lock);
181 ras_fwlog->state = INACTIVE;
182 - spin_unlock_irq(&phba->hbalock);
183 + spin_unlock_irq(&phba->ras_fwlog_lock);
185 /* Disable FW logging to host memory */
186 writel(LPFC_CTL_PDEV_CTL_DDL_RAS,
187 @@ -6889,9 +6889,9 @@ lpfc_sli4_ras_dma_free(struct lpfc_hba *phba)
188 ras_fwlog->lwpd.virt = NULL;
191 - spin_lock_irq(&phba->hbalock);
192 + spin_lock_irq(&phba->ras_fwlog_lock);
193 ras_fwlog->state = INACTIVE;
194 - spin_unlock_irq(&phba->hbalock);
195 + spin_unlock_irq(&phba->ras_fwlog_lock);
199 @@ -6993,9 +6993,9 @@ lpfc_sli4_ras_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
203 - spin_lock_irq(&phba->hbalock);
204 + spin_lock_irq(&phba->ras_fwlog_lock);
205 ras_fwlog->state = ACTIVE;
206 - spin_unlock_irq(&phba->hbalock);
207 + spin_unlock_irq(&phba->ras_fwlog_lock);
208 mempool_free(pmb, phba->mbox_mem_pool);
211 @@ -7027,9 +7027,9 @@ lpfc_sli4_ras_fwlog_init(struct lpfc_hba *phba,
212 uint32_t len = 0, fwlog_buffsize, fwlog_entry_count;
215 - spin_lock_irq(&phba->hbalock);
216 + spin_lock_irq(&phba->ras_fwlog_lock);
217 ras_fwlog->state = INACTIVE;
218 - spin_unlock_irq(&phba->hbalock);
219 + spin_unlock_irq(&phba->ras_fwlog_lock);
221 fwlog_buffsize = (LPFC_RAS_MIN_BUFF_POST_SIZE *
222 phba->cfg_ras_fwlog_buffsize);
223 @@ -7090,9 +7090,9 @@ lpfc_sli4_ras_fwlog_init(struct lpfc_hba *phba,
224 mbx_fwlog->u.request.lwpd.addr_lo = putPaddrLow(ras_fwlog->lwpd.phys);
225 mbx_fwlog->u.request.lwpd.addr_hi = putPaddrHigh(ras_fwlog->lwpd.phys);
227 - spin_lock_irq(&phba->hbalock);
228 + spin_lock_irq(&phba->ras_fwlog_lock);
229 ras_fwlog->state = REG_INPROGRESS;
230 - spin_unlock_irq(&phba->hbalock);
231 + spin_unlock_irq(&phba->ras_fwlog_lock);
232 mbox->vport = phba->pport;
233 mbox->mbox_cmpl = lpfc_sli4_ras_mbox_cmpl;