Skip to content

Commit 6d0b655

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Flush mailbox commands on chip reset
Fix race condition between Interrupt thread and Chip reset thread in trying to flush the same mailbox. With the race condition, the "ha->mbx_intr_comp" will get an extra complete() call. The extra complete call create erroneous mailbox timeout condition when the next mailbox is sent where the mailbox call does not wait for interrupt to arrive. Instead, it advances without waiting. Add lock protection around the check for mailbox completion. Cc: stable@vger.kernel.org Fixes: b200080 ("scsi: qla2xxx: Flush mailbox commands on chip reset") Signed-off-by: Quinn Tran <quinn.tran@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Link: https://lore.kernel.org/r/20230821130045.34850-3-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 875386b commit 6d0b655

File tree

4 files changed

+4
-9
lines changed

4 files changed

+4
-9
lines changed

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4418,7 +4418,6 @@ struct qla_hw_data {
44184418
uint8_t aen_mbx_count;
44194419
atomic_t num_pend_mbx_stage1;
44204420
atomic_t num_pend_mbx_stage2;
4421-
atomic_t num_pend_mbx_stage3;
44224421
uint16_t frame_payload_size;
44234422

44244423
uint32_t login_retry_count;

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7391,14 +7391,15 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
73917391
}
73927392

73937393
/* purge MBox commands */
7394-
if (atomic_read(&ha->num_pend_mbx_stage3)) {
7394+
spin_lock_irqsave(&ha->hardware_lock, flags);
7395+
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) {
73957396
clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
73967397
complete(&ha->mbx_intr_comp);
73977398
}
7399+
spin_unlock_irqrestore(&ha->hardware_lock, flags);
73987400

73997401
i = 0;
7400-
while (atomic_read(&ha->num_pend_mbx_stage3) ||
7401-
atomic_read(&ha->num_pend_mbx_stage2) ||
7402+
while (atomic_read(&ha->num_pend_mbx_stage2) ||
74027403
atomic_read(&ha->num_pend_mbx_stage1)) {
74037404
msleep(20);
74047405
i++;

drivers/scsi/qla2xxx/qla_mbx.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
273273
spin_unlock_irqrestore(&ha->hardware_lock, flags);
274274

275275
wait_time = jiffies;
276-
atomic_inc(&ha->num_pend_mbx_stage3);
277276
if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
278277
mcp->tov * HZ)) {
279278
ql_dbg(ql_dbg_mbx, vha, 0x117a,
@@ -290,7 +289,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
290289
spin_unlock_irqrestore(&ha->hardware_lock,
291290
flags);
292291
atomic_dec(&ha->num_pend_mbx_stage2);
293-
atomic_dec(&ha->num_pend_mbx_stage3);
294292
rval = QLA_ABORTED;
295293
goto premature_exit;
296294
}
@@ -302,11 +300,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
302300
ha->flags.mbox_busy = 0;
303301
spin_unlock_irqrestore(&ha->hardware_lock, flags);
304302
atomic_dec(&ha->num_pend_mbx_stage2);
305-
atomic_dec(&ha->num_pend_mbx_stage3);
306303
rval = QLA_ABORTED;
307304
goto premature_exit;
308305
}
309-
atomic_dec(&ha->num_pend_mbx_stage3);
310306

311307
if (time_after(jiffies, wait_time + 5 * HZ))
312308
ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3008,7 +3008,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
30083008
ha->max_exchg = FW_MAX_EXCHANGES_CNT;
30093009
atomic_set(&ha->num_pend_mbx_stage1, 0);
30103010
atomic_set(&ha->num_pend_mbx_stage2, 0);
3011-
atomic_set(&ha->num_pend_mbx_stage3, 0);
30123011
atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD);
30133012
ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD;
30143013
INIT_LIST_HEAD(&ha->tmf_pending);

0 commit comments

Comments
 (0)