Michal Suchanek f2e744
From d5b45dd5ba6c944b17118530843e67bf9c096e49 Mon Sep 17 00:00:00 2001
Michal Suchanek f2e744
From: Brian King <brking@linux.vnet.ibm.com>
Michal Suchanek f2e744
Date: Tue, 11 May 2021 13:12:18 -0500
Michal Suchanek f2e744
Subject: [PATCH] scsi: ibmvfc: Handle move login failure
Michal Suchanek f2e744
Michal Suchanek f2e744
References: bsc#1185938 ltc#192043
Michal Kubecek 9a3a83
Patch-mainline: v5.14-rc1
Michal Suchanek f2e744
Git-commit: d5b45dd5ba6c944b17118530843e67bf9c096e49
Michal Suchanek f2e744
Michal Suchanek f2e744
When service is being performed on an SVC with NPIV enabled, the WWPN of
Michal Suchanek f2e744
the canister / node being serviced fails over to the another canister /
Michal Suchanek f2e744
node. This looks to the ibmvfc driver as a WWPN moving from one SCSI ID to
Michal Suchanek f2e744
another. The driver will first attempt to do an implicit logout of the old
Michal Suchanek f2e744
SCSI ID. If this works, we simply delete the rport at the old location and
Michal Suchanek f2e744
add an rport at the new location and the FC transport class handles
Michal Suchanek f2e744
everything. However, if there is I/O outstanding, this implicit logout will
Michal Suchanek f2e744
fail, in which case we will send a "move login" request to the VIOS. This
Michal Suchanek f2e744
will cancel any outstanding I/O to that port, logout the port, and PLOGI
Michal Suchanek f2e744
the new port. Recently we've encountered a scenario where the move login
Michal Suchanek f2e744
fails. This was resulting in an attempted plogi to the new scsi id, without
Michal Suchanek f2e744
the old scsi id getting logged out, which is a VIOS protocol violation. To
Michal Suchanek f2e744
solve this, we want to keep tracking the old scsi id as the current scsi
Michal Suchanek f2e744
id. That way, once terminate_rport_io cancels the outstanding i/o, it will
Michal Suchanek f2e744
send us back through to do an implicit logout of the old scsi id, rather
Michal Suchanek f2e744
than the new scsi id, and then we can plogi the new scsi id.
Michal Suchanek f2e744
Michal Suchanek f2e744
Link: https://lore.kernel.org/r/1620756740-7045-2-git-send-email-brking@linux.vnet.ibm.com
Michal Suchanek f2e744
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Michal Suchanek f2e744
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Michal Suchanek f2e744
Acked-by: Michal Suchanek <msuchanek@suse.de>
Michal Suchanek f2e744
---
Michal Suchanek f2e744
 drivers/scsi/ibmvscsi/ibmvfc.c | 16 ++++++++--------
Michal Suchanek f2e744
 drivers/scsi/ibmvscsi/ibmvfc.h |  2 +-
Michal Suchanek f2e744
 2 files changed, 9 insertions(+), 9 deletions(-)
Michal Suchanek f2e744
Michal Suchanek f2e744
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
Michal Suchanek f2e744
index 6540d48eb0e8..4ac5bff69305 100644
Michal Suchanek f2e744
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
Michal Suchanek f2e744
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
Michal Suchanek f2e744
@@ -4299,9 +4299,10 @@ static void ibmvfc_tgt_move_login_done(struct ibmvfc_event *evt)
Michal Suchanek f2e744
 	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
Michal Suchanek f2e744
 	switch (status) {
Michal Suchanek f2e744
 	case IBMVFC_MAD_SUCCESS:
Michal Suchanek f2e744
-		tgt_dbg(tgt, "Move Login succeeded for old scsi_id: %llX\n", tgt->old_scsi_id);
Michal Suchanek f2e744
+		tgt_dbg(tgt, "Move Login succeeded for new scsi_id: %llX\n", tgt->new_scsi_id);
Michal Suchanek f2e744
 		tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name);
Michal Suchanek f2e744
 		tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name);
Michal Suchanek f2e744
+		tgt->scsi_id = tgt->new_scsi_id;
Michal Suchanek f2e744
 		tgt->ids.port_id = tgt->scsi_id;
Michal Suchanek f2e744
 		memcpy(&tgt->service_parms, &rsp->service_parms,
Michal Suchanek f2e744
 		       sizeof(tgt->service_parms));
Michal Suchanek f2e744
@@ -4319,8 +4320,8 @@ static void ibmvfc_tgt_move_login_done(struct ibmvfc_event *evt)
Michal Suchanek f2e744
 		level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_move_login);
Michal Suchanek f2e744
 
Michal Suchanek f2e744
 		tgt_log(tgt, level,
Michal Suchanek f2e744
-			"Move Login failed: old scsi_id: %llX, flags:%x, vios_flags:%x, rc=0x%02X\n",
Michal Suchanek f2e744
-			tgt->old_scsi_id, be32_to_cpu(rsp->flags), be16_to_cpu(rsp->vios_flags),
Michal Suchanek f2e744
+			"Move Login failed: new scsi_id: %llX, flags:%x, vios_flags:%x, rc=0x%02X\n",
Michal Suchanek f2e744
+			tgt->new_scsi_id, be32_to_cpu(rsp->flags), be16_to_cpu(rsp->vios_flags),
Michal Suchanek f2e744
 			status);
Michal Suchanek f2e744
 		break;
Michal Suchanek f2e744
 	}
Michal Suchanek f2e744
@@ -4357,8 +4358,8 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *tgt)
Michal Suchanek f2e744
 	move->common.opcode = cpu_to_be32(IBMVFC_MOVE_LOGIN);
Michal Suchanek f2e744
 	move->common.length = cpu_to_be16(sizeof(*move));
Michal Suchanek f2e744
 
Michal Suchanek f2e744
-	move->old_scsi_id = cpu_to_be64(tgt->old_scsi_id);
Michal Suchanek f2e744
-	move->new_scsi_id = cpu_to_be64(tgt->scsi_id);
Michal Suchanek f2e744
+	move->old_scsi_id = cpu_to_be64(tgt->scsi_id);
Michal Suchanek f2e744
+	move->new_scsi_id = cpu_to_be64(tgt->new_scsi_id);
Michal Suchanek f2e744
 	move->wwpn = cpu_to_be64(tgt->wwpn);
Michal Suchanek f2e744
 	move->node_name = cpu_to_be64(tgt->ids.node_name);
Michal Suchanek f2e744
 
Michal Suchanek f2e744
@@ -4367,7 +4368,7 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *tgt)
Michal Suchanek f2e744
 		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
Michal Suchanek f2e744
 		kref_put(&tgt->kref, ibmvfc_release_tgt);
Michal Suchanek f2e744
 	} else
Michal Suchanek f2e744
-		tgt_dbg(tgt, "Sent Move Login for old scsi_id: %llX\n", tgt->old_scsi_id);
Michal Suchanek f2e744
+		tgt_dbg(tgt, "Sent Move Login for new scsi_id: %llX\n", tgt->new_scsi_id);
Michal Suchanek f2e744
 }
Michal Suchanek f2e744
 
Michal Suchanek f2e744
 /**
Michal Suchanek f2e744
@@ -4737,8 +4738,7 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost,
Michal Suchanek f2e744
 			 * normal ibmvfc_set_tgt_action to set this, as we
Michal Suchanek f2e744
 			 * don't normally want to allow this state change.
Michal Suchanek f2e744
 			 */
Michal Suchanek f2e744
-			wtgt->old_scsi_id = wtgt->scsi_id;
Michal Suchanek f2e744
-			wtgt->scsi_id = scsi_id;
Michal Suchanek f2e744
+			wtgt->new_scsi_id = scsi_id;
Michal Suchanek f2e744
 			wtgt->action = IBMVFC_TGT_ACTION_INIT;
Michal Suchanek f2e744
 			ibmvfc_init_tgt(wtgt, ibmvfc_tgt_move_login);
Michal Suchanek f2e744
 			goto unlock_out;
Michal Suchanek f2e744
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
Michal Suchanek f2e744
index 19dcec3ae9ba..4601bd21372d 100644
Michal Suchanek f2e744
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
Michal Suchanek f2e744
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
Michal Suchanek f2e744
@@ -718,7 +718,7 @@ struct ibmvfc_target {
Michal Suchanek f2e744
 	struct ibmvfc_host *vhost;
Michal Suchanek f2e744
 	u64 scsi_id;
Michal Suchanek f2e744
 	u64 wwpn;
Michal Suchanek f2e744
-	u64 old_scsi_id;
Michal Suchanek f2e744
+	u64 new_scsi_id;
Michal Suchanek f2e744
 	struct fc_rport *rport;
Michal Suchanek f2e744
 	int target_id;
Michal Suchanek f2e744
 	enum ibmvfc_target_action action;
Michal Suchanek f2e744
-- 
Michal Suchanek f2e744
2.26.2
Michal Suchanek f2e744