[PATCH 5.15 396/779] scsi: qla2xxx: edif: Reduce connection thrash

From: Greg Kroah-Hartman
Date: Mon Aug 15 2022 - 15:09:59 EST


From: Quinn Tran <qutran@xxxxxxxxxxx>

[ Upstream commit 91f6f5fbe87ba834133fcc61d34881cb8ec9e518 ]

On ipsec start by remote port, target port may use RSCN to trigger
initiator to relogin. If driver is already in the process of a relogin,
then ignore the RSCN and allow the current relogin to continue. This
reduces thrashing of the connection.

Link: https://lore.kernel.org/r/20211026115412.27691-10-njavali@xxxxxxxxxxx
Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx>
Signed-off-by: Quinn Tran <qutran@xxxxxxxxxxx>
Signed-off-by: Nilesh Javali <njavali@xxxxxxxxxxx>
Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
drivers/scsi/qla2xxx/qla_attr.c | 7 ++++++-
drivers/scsi/qla2xxx/qla_edif.h | 4 ++++
drivers/scsi/qla2xxx/qla_init.c | 24 ++++++++++++++++++++++--
3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index d3534e7f2d21..bd4ebc1b5c1e 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -2754,7 +2754,12 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
if (fcport->loop_id != FC_NO_LOOP_ID)
fcport->logout_on_delete = 1;

- qlt_schedule_sess_for_deletion(fcport);
+ if (!EDIF_NEGOTIATION_PENDING(fcport)) {
+ ql_dbg(ql_dbg_disc, fcport->vha, 0x911e,
+ "%s %d schedule session deletion\n", __func__,
+ __LINE__);
+ qlt_schedule_sess_for_deletion(fcport);
+ }
} else {
qla2x00_port_logout(fcport->vha, fcport);
}
diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h
index 32800bfb32a3..2517005fb08c 100644
--- a/drivers/scsi/qla2xxx/qla_edif.h
+++ b/drivers/scsi/qla2xxx/qla_edif.h
@@ -133,4 +133,8 @@ struct enode {
_s->disc_state == DSC_DELETED || \
!_s->edif.app_sess_online))

+#define EDIF_NEGOTIATION_PENDING(_fcport) \
+ ((_fcport->vha.e_dbell.db_flags & EDB_ACTIVE) && \
+ (_fcport->disc_state == DSC_LOGIN_AUTH_PEND))
+
#endif /* __QLA_EDIF_H */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index be150fc76dba..09ddaa8cb653 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1825,8 +1825,28 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
fcport->d_id.b24, fcport->port_name);
return;
}
- fcport->scan_needed = 1;
- fcport->rscn_gen++;
+
+ if (vha->hw->flags.edif_enabled && vha->e_dbell.db_flags & EDB_ACTIVE) {
+ /*
+ * On ipsec start by remote port, Target port
+ * may use RSCN to trigger initiator to
+ * relogin. If driver is already in the
+ * process of a relogin, then ignore the RSCN
+ * and allow the current relogin to continue.
+ * This reduces thrashing of the connection.
+ */
+ if (atomic_read(&fcport->state) == FCS_ONLINE) {
+ /*
+ * If state = online, then set scan_needed=1 to do relogin.
+ * Otherwise we're already in the middle of a relogin
+ */
+ fcport->scan_needed = 1;
+ fcport->rscn_gen++;
+ }
+ } else {
+ fcport->scan_needed = 1;
+ fcport->rscn_gen++;
+ }
}
break;
case RSCN_AREA_ADDR:
--
2.35.1