scsi: qla2xxx: edif: Fix potential stuck session in sa update
authorQuinn Tran <qutran@marvell.com>
Tue, 7 Jun 2022 04:46:21 +0000 (21:46 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Aug 2022 12:23:39 +0000 (14:23 +0200)
[ Upstream commit e0fb8ce2bb9e52c846e54ad2c58b5b7beb13eb09 ]

When a thread is in the process of reestablish a session, a flag is set to
prevent multiple threads/triggers from doing the same task. This flag was
left on, and any attempt to relogin was locked out. Clear this flag if the
attempt has failed.

Link: https://lore.kernel.org/r/20220607044627.19563-6-njavali@marvell.com
Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/qla2xxx/qla_edif.c

index e421416..4be876d 100644 (file)
@@ -2187,6 +2187,7 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr,
 
 static void qla_noop_sp_done(srb_t *sp, int res)
 {
+       sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        /* ref: INIT */
        kref_put(&sp->cmd_kref, qla2x00_sp_release);
 }
@@ -2211,7 +2212,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
        if (!sa_ctl) {
                ql_dbg(ql_dbg_edif, vha, 0x70e6,
                    "sa_ctl allocation failed\n");
-               return -ENOMEM;
+               rval =  -ENOMEM;
+               goto done;
        }
 
        fcport = sa_ctl->fcport;
@@ -2221,7 +2223,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
        if (!sp) {
                ql_dbg(ql_dbg_edif, vha, 0x70e6,
                 "SRB allocation failed\n");
-               return -ENOMEM;
+               rval = -ENOMEM;
+               goto done;
        }
 
        fcport->flags |= FCF_ASYNC_SENT;
@@ -2250,10 +2253,18 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
 
        rval = qla2x00_start_sp(sp);
 
-       if (rval != QLA_SUCCESS)
+       if (rval != QLA_SUCCESS) {
                rval = QLA_FUNCTION_FAILED;
+               goto done_free_sp;
+       }
 
        return rval;
+done_free_sp:
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
+       fcport->flags &= ~FCF_ASYNC_SENT;
+done:
+       fcport->flags &= ~FCF_ASYNC_ACTIVE;
+       return rval;
 }
 
 void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb)