Commit 4b29cb61 authored by Brian King's avatar Brian King Committed by Martin K. Petersen

scsi: ibmvfc: Avoid link down on FS9100 canister reboot

When a canister on a FS9100, or similar storage, running in NPIV mode, is
rebooted, its WWPNs will fail over to another canister. When this occurs,
we see a WWPN going away from the fabric at one N-Port ID, and, a short
time later, the same WWPN appears at a different N-Port ID.  When the
canister is fully operational again, the WWPNs fail back to the original
canister. If there is any I/O outstanding to the target when this occurs,
it will result in the implicit logout the ibmvfc driver issues before
removing the rport to fail. When the WWPN then shows up at a different
N-Port ID, and we issue a PLOGI to it, the VIOS will see that it still has
a login for this WWPN at the old N-Port ID, which results in the VIOS
simulating a link down / link up sequence to the client, in order to get
the VIOS and client LPAR in sync.

The patch below improves the way we handle this scenario so as to avoid the
link bounce, which affects all targets under the virtual host adapter. The
change is to utilize the Move Login MAD, which will work even when I/O is
outstanding to the target. The change only alters the target state machine
for the case where the implicit logout fails prior to deleting the rport.
If this implicit logout fails, we defer deleting the ibmvfc_target object
after calling fc_remote_port_delete. This enables us to later retry the
implicit logout after terminate_rport_io occurs, or to issue the Move Login
request if a WWPN shows up at a new N-Port ID prior to this occurring.

This has been tested by IBM's storage interoperability team on a FS9100,
forcing the failover to occur. With debug tracing enabled in the ibmvfc
driver, we confirmed the move login was sent in this scenario and confirmed
the link bounce no longer occurred.

[mkp: fix checkpatch warnings]

Link: https://lore.kernel.org/r/1599859706-8505-1-git-send-email-brking@linux.vnet.ibm.comSigned-off-by: default avatarBrian King <brking@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 46c9d608
This diff is collapsed.
......@@ -120,6 +120,7 @@ enum ibmvfc_mad_types {
IBMVFC_PORT_LOGIN = 0x0004,
IBMVFC_PROCESS_LOGIN = 0x0008,
IBMVFC_QUERY_TARGET = 0x0010,
IBMVFC_MOVE_LOGIN = 0x0020,
IBMVFC_IMPLICIT_LOGOUT = 0x0040,
IBMVFC_PASSTHRU = 0x0200,
IBMVFC_TMF_MAD = 0x0100,
......@@ -197,6 +198,7 @@ struct ibmvfc_service_parms {
__be32 ext_len;
__be32 reserved[30];
__be32 clk_sync_qos[2];
__be32 reserved2;
} __packed __aligned(4);
struct ibmvfc_npiv_login_resp {
......@@ -230,15 +232,18 @@ union ibmvfc_npiv_login_data {
struct ibmvfc_npiv_login_resp resp;
} __packed __aligned(8);
struct ibmvfc_discover_targets_buf {
__be32 scsi_id[1];
struct ibmvfc_discover_targets_entry {
__be32 scsi_id;
__be32 pad;
__be64 wwpn;
#define IBMVFC_DISC_TGT_SCSI_ID_MASK 0x00ffffff
};
} __packed __aligned(8);
struct ibmvfc_discover_targets {
struct ibmvfc_mad_common common;
struct srp_direct_buf buffer;
__be32 flags;
#define IBMVFC_DISC_TGT_PORT_ID_WWPN_LIST 0x02
__be16 status;
__be16 error;
__be32 bufflen;
......@@ -291,6 +296,26 @@ struct ibmvfc_port_login {
__be64 reserved3[2];
} __packed __aligned(8);
struct ibmvfc_move_login {
struct ibmvfc_mad_common common;
__be64 old_scsi_id;
__be64 new_scsi_id;
__be64 wwpn;
__be64 node_name;
__be32 flags;
#define IBMVFC_MOVE_LOGIN_IMPLICIT_OLD_FAILED 0x01
#define IBMVFC_MOVE_LOGIN_IMPLICIT_NEW_FAILED 0x02
#define IBMVFC_MOVE_LOGIN_PORT_LOGIN_FAILED 0x04
__be32 reserved;
struct ibmvfc_service_parms service_parms;
struct ibmvfc_service_parms service_parms_change;
__be32 reserved2;
__be16 service_class;
__be16 vios_flags;
#define IBMVFC_MOVE_LOGIN_VF_NOT_SENT_ADAPTER 0x01
__be64 reserved3;
} __packed __aligned(8);
struct ibmvfc_prli_svc_parms {
u8 type;
#define IBMVFC_SCSI_FCP_TYPE 0x08
......@@ -646,6 +671,7 @@ union ibmvfc_iu {
struct ibmvfc_discover_targets discover_targets;
struct ibmvfc_port_login plogi;
struct ibmvfc_process_login prli;
struct ibmvfc_move_login move_login;
struct ibmvfc_query_tgt query_tgt;
struct ibmvfc_implicit_logout implicit_logout;
struct ibmvfc_tmf tmf;
......@@ -664,12 +690,16 @@ enum ibmvfc_target_action {
IBMVFC_TGT_ACTION_LOGOUT_RPORT_WAIT,
IBMVFC_TGT_ACTION_DEL_RPORT,
IBMVFC_TGT_ACTION_DELETED_RPORT,
IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT,
IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT,
};
struct ibmvfc_target {
struct list_head queue;
struct ibmvfc_host *vhost;
u64 scsi_id;
u64 wwpn;
u64 old_scsi_id;
struct fc_rport *rport;
int target_id;
enum ibmvfc_target_action action;
......@@ -765,7 +795,7 @@ struct ibmvfc_host {
dma_addr_t login_buf_dma;
int disc_buf_sz;
int log_level;
struct ibmvfc_discover_targets_buf *disc_buf;
struct ibmvfc_discover_targets_entry *disc_buf;
struct mutex passthru_mutex;
int task_set;
int init_retries;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment