Michal Suchanek 535566
From 5114975eb2de4e70d9d43b57912e1aee12ec090b Mon Sep 17 00:00:00 2001
Michal Suchanek 535566
From: Brian King <brking@linux.vnet.ibm.com>
Michal Suchanek 535566
Date: Tue, 11 May 2021 13:12:19 -0500
Michal Suchanek 535566
Subject: [PATCH] scsi: ibmvfc: Avoid move login if fast fail is enabled
Michal Suchanek 535566
Michal Suchanek 535566
References: bsc#1185938 ltc#192043
Michal Kubecek 9a3a83
Patch-mainline: v5.14-rc1
Michal Suchanek 535566
Git-commit: 5114975eb2de4e70d9d43b57912e1aee12ec090b
Michal Suchanek 535566
Michal Suchanek 535566
If fast fail is enabled and we encounter a WWPN moving from one port id to
Michal Suchanek 535566
another port id with I/O outstanding, if we use the move login MAD,
Michal Suchanek 535566
although it will work, it will leave any outstanding I/O still outstanding
Michal Suchanek 535566
to the old port id. Eventually, the SCSI command timers will fire and we
Michal Suchanek 535566
will abort these commands, however, this is generally much longer than the
Michal Suchanek 535566
fast fail timeout, which can lead to I/O operations being outstanding for a
Michal Suchanek 535566
long time. This patch changes the behavior to avoid the move login if fast
Michal Suchanek 535566
fail is enabled. Once terminate_rport_io cleans up the rport, then we force
Michal Suchanek 535566
the target back through the delete process, which re-drives the implicit
Michal Suchanek 535566
logout, then kicks us back into discovery where we will discover the WWPN
Michal Suchanek 535566
at the new location and do a PLOGI to it.
Michal Suchanek 535566
Michal Suchanek 535566
Link: https://lore.kernel.org/r/1620756740-7045-3-git-send-email-brking@linux.vnet.ibm.com
Michal Suchanek 535566
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Michal Suchanek 535566
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Michal Suchanek 535566
Acked-by: Michal Suchanek <msuchanek@suse.de>
Michal Suchanek 535566
---
Michal Suchanek 535566
 drivers/scsi/ibmvscsi/ibmvfc.c | 39 ++++++++++++++++++++++++----------
Michal Suchanek 535566
 drivers/scsi/ibmvscsi/ibmvfc.h |  1 +
Michal Suchanek 535566
 2 files changed, 29 insertions(+), 11 deletions(-)
Michal Suchanek 535566
Michal Suchanek 535566
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
Michal Suchanek 535566
index 4ac5bff69305..c8d3fdf65a7f 100644
Michal Suchanek 535566
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
Michal Suchanek 535566
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
Michal Suchanek 535566
@@ -4728,19 +4728,24 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost,
Michal Suchanek 535566
 		 * and it failed for some reason, such as there being I/O
Michal Suchanek 535566
 		 * pending to the target. In this case, we will have already
Michal Suchanek 535566
 		 * deleted the rport from the FC transport so we do a move
Michal Suchanek 535566
-		 * login, which works even with I/O pending, as it will cancel
Michal Suchanek 535566
-		 * any active commands.
Michal Suchanek 535566
+		 * login, which works even with I/O pending, however, if
Michal Suchanek 535566
+		 * there is still I/O pending, it will stay outstanding, so
Michal Suchanek 535566
+		 * we only do this if fast fail is disabled for the rport,
Michal Suchanek 535566
+		 * otherwise we let terminate_rport_io clean up the port
Michal Suchanek 535566
+		 * before we login at the new location.
Michal Suchanek 535566
 		 */
Michal Suchanek 535566
 		if (wtgt->action == IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT) {
Michal Suchanek 535566
-			/*
Michal Suchanek 535566
-			 * Do a move login here. The old target is no longer
Michal Suchanek 535566
-			 * known to the transport layer We don't use the
Michal Suchanek 535566
-			 * normal ibmvfc_set_tgt_action to set this, as we
Michal Suchanek 535566
-			 * don't normally want to allow this state change.
Michal Suchanek 535566
-			 */
Michal Suchanek 535566
-			wtgt->new_scsi_id = scsi_id;
Michal Suchanek 535566
-			wtgt->action = IBMVFC_TGT_ACTION_INIT;
Michal Suchanek 535566
-			ibmvfc_init_tgt(wtgt, ibmvfc_tgt_move_login);
Michal Suchanek 535566
+			if (wtgt->move_login) {
Michal Suchanek 535566
+				/*
Michal Suchanek 535566
+				 * Do a move login here. The old target is no longer
Michal Suchanek 535566
+				 * known to the transport layer We don't use the
Michal Suchanek 535566
+				 * normal ibmvfc_set_tgt_action to set this, as we
Michal Suchanek 535566
+				 * don't normally want to allow this state change.
Michal Suchanek 535566
+				 */
Michal Suchanek 535566
+				wtgt->new_scsi_id = scsi_id;
Michal Suchanek 535566
+				wtgt->action = IBMVFC_TGT_ACTION_INIT;
Michal Suchanek 535566
+				ibmvfc_init_tgt(wtgt, ibmvfc_tgt_move_login);
Michal Suchanek 535566
+			}
Michal Suchanek 535566
 			goto unlock_out;
Michal Suchanek 535566
 		} else {
Michal Suchanek 535566
 			tgt_err(wtgt, "Unexpected target state: %d, %p\n",
Michal Suchanek 535566
@@ -5486,6 +5491,18 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
Michal Suchanek 535566
 				rport = tgt->rport;
Michal Suchanek 535566
 				tgt->rport = NULL;
Michal Suchanek 535566
 				ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT);
Michal Suchanek 535566
+
Michal Suchanek 535566
+				/*
Michal Suchanek 535566
+				 * If fast fail is enabled, we wait for it to fire and then clean up
Michal Suchanek 535566
+				 * the old port, since we expect the fast fail timer to clean up the
Michal Suchanek 535566
+				 * outstanding I/O faster than waiting for normal command timeouts.
Michal Suchanek 535566
+				 * However, if fast fail is disabled, any I/O outstanding to the
Michal Suchanek 535566
+				 * rport LUNs will stay outstanding indefinitely, since the EH handlers
Michal Suchanek 535566
+				 * won't get invoked for I/O's timing out. If this is a NPIV failover
Michal Suchanek 535566
+				 * scenario, the better alternative is to use the move login.
Michal Suchanek 535566
+				 */
Michal Suchanek 535566
+				if (rport && rport->fast_io_fail_tmo == -1)
Michal Suchanek 535566
+					tgt->move_login = 1;
Michal Suchanek 535566
 				spin_unlock_irqrestore(vhost->host->host_lock, flags);
Michal Suchanek 535566
 				if (rport)
Michal Suchanek 535566
 					fc_remote_port_delete(rport);
Michal Suchanek 535566
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
Michal Suchanek 535566
index 4601bd21372d..4f0f3baefae4 100644
Michal Suchanek 535566
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
Michal Suchanek 535566
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
Michal Suchanek 535566
@@ -726,6 +726,7 @@ struct ibmvfc_target {
Michal Suchanek 535566
 	int add_rport;
Michal Suchanek 535566
 	int init_retries;
Michal Suchanek 535566
 	int logo_rcvd;
Michal Suchanek 535566
+	int move_login;
Michal Suchanek 535566
 	u32 cancel_key;
Michal Suchanek 535566
 	struct ibmvfc_service_parms service_parms;
Michal Suchanek 535566
 	struct ibmvfc_service_parms service_parms_change;
Michal Suchanek 535566
-- 
Michal Suchanek 535566
2.26.2
Michal Suchanek 535566