scsi: qla2xxx: Flush mailbox commands on chip reset
authorQuinn Tran <qutran@marvell.com>
Mon, 21 Aug 2023 13:00:38 +0000 (18:30 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 21 Aug 2023 21:45:14 +0000 (17:45 -0400)
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: b2000805a975 ("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>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c

index 2007d5bb5f9f831e4465a0b735b11737114ec06e..f1cf921068e3be93848451061765a8038bfbb344 100644 (file)
@@ -4418,7 +4418,6 @@ struct qla_hw_data {
        uint8_t         aen_mbx_count;
        atomic_t        num_pend_mbx_stage1;
        atomic_t        num_pend_mbx_stage2;
-       atomic_t        num_pend_mbx_stage3;
        uint16_t        frame_payload_size;
 
        uint32_t        login_retry_count;
index 27644957ae4eed0fb05d8755cc05f8c1637bdd5b..d38b77a296373e088708906ab79a53d49ea1b0e3 100644 (file)
@@ -7391,14 +7391,15 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
        }
 
        /* purge MBox commands */
-       if (atomic_read(&ha->num_pend_mbx_stage3)) {
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) {
                clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
                complete(&ha->mbx_intr_comp);
        }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        i = 0;
-       while (atomic_read(&ha->num_pend_mbx_stage3) ||
-           atomic_read(&ha->num_pend_mbx_stage2) ||
+       while (atomic_read(&ha->num_pend_mbx_stage2) ||
            atomic_read(&ha->num_pend_mbx_stage1)) {
                msleep(20);
                i++;
index b05f930378756e4f650612cbf7f858ea8ea870cd..21ec32b4fb2809321ee6498255e63662cc094fb0 100644 (file)
@@ -273,7 +273,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
                wait_time = jiffies;
-               atomic_inc(&ha->num_pend_mbx_stage3);
                if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
                    mcp->tov * HZ)) {
                        ql_dbg(ql_dbg_mbx, vha, 0x117a,
@@ -290,7 +289,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
                                spin_unlock_irqrestore(&ha->hardware_lock,
                                    flags);
                                atomic_dec(&ha->num_pend_mbx_stage2);
-                               atomic_dec(&ha->num_pend_mbx_stage3);
                                rval = QLA_ABORTED;
                                goto premature_exit;
                        }
@@ -302,11 +300,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
                        ha->flags.mbox_busy = 0;
                        spin_unlock_irqrestore(&ha->hardware_lock, flags);
                        atomic_dec(&ha->num_pend_mbx_stage2);
-                       atomic_dec(&ha->num_pend_mbx_stage3);
                        rval = QLA_ABORTED;
                        goto premature_exit;
                }
-               atomic_dec(&ha->num_pend_mbx_stage3);
 
                if (time_after(jiffies, wait_time + 5 * HZ))
                        ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
index aa492489a4b84cf785c6ea917c1d7c3c0c71919f..e380634c8e2568fe56c82344bc05034fbb093f59 100644 (file)
@@ -3008,7 +3008,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ha->max_exchg = FW_MAX_EXCHANGES_CNT;
        atomic_set(&ha->num_pend_mbx_stage1, 0);
        atomic_set(&ha->num_pend_mbx_stage2, 0);
-       atomic_set(&ha->num_pend_mbx_stage3, 0);
        atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD);
        ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD;
        INIT_LIST_HEAD(&ha->tmf_pending);