scsi: qla2xxx: Fix login timeout
authorQuinn Tran <qutran@marvell.com>
Thu, 6 Aug 2020 11:10:07 +0000 (04:10 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 18 Aug 2020 02:40:12 +0000 (22:40 -0400)
Multipath errors were seen during failback due to login timeout.  The
remote device sent LOGO, the local host tore down the session and did
relogin. The RSCN arrived indicates remote device is going through failover
after which the relogin is in a 20s timeout phase.  At this point the
driver is stuck in the relogin process.  Add a fix to delete the session as
part of abort/flush the login.

Link: https://lore.kernel.org/r/20200806111014.28434-5-njavali@marvell.com
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
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>
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_target.c

index 3bfb5678f6515a904b9494426f6e439bd43e7fe3..de9fd7f688d014dca79eba9fde812ae63e14c91e 100644 (file)
@@ -3538,10 +3538,22 @@ login_logout:
                }
 
                if (fcport->scan_state != QLA_FCPORT_FOUND) {
+                       bool do_delete = false;
+
+                       if (fcport->scan_needed &&
+                           fcport->disc_state == DSC_LOGIN_PEND) {
+                               /* Cable got disconnected after we sent
+                                * a login. Do delete to prevent timeout.
+                                */
+                               fcport->logout_on_delete = 1;
+                               do_delete = true;
+                       }
+
                        fcport->scan_needed = 0;
-                       if ((qla_dual_mode_enabled(vha) ||
-                               qla_ini_mode_enabled(vha)) &&
-                           atomic_read(&fcport->state) == FCS_ONLINE) {
+                       if (((qla_dual_mode_enabled(vha) ||
+                             qla_ini_mode_enabled(vha)) &&
+                           atomic_read(&fcport->state) == FCS_ONLINE) ||
+                               do_delete) {
                                if (fcport->loop_id != FC_NO_LOOP_ID) {
                                        if (fcport->flags & FCF_FCP2_DEVICE)
                                                fcport->logout_on_delete = 0;
index fbb80a043b4fe0d102218e916febae8a434d1c3c..90289162dbd4c748a50721aa1766b669d53339a0 100644 (file)
@@ -1270,7 +1270,7 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
 
        qla24xx_chk_fcp_state(sess);
 
-       ql_dbg(ql_dbg_tgt, sess->vha, 0xe001,
+       ql_dbg(ql_dbg_disc, sess->vha, 0xe001,
            "Scheduling sess %p for deletion %8phC\n",
            sess, sess->port_name);