Commit f8844457 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Fix NVMe retry

For target port that register itself as both FCP + NVMe, initiator driver
will try to login one mode at a time. If the last mode did not succeed,
then driver will try the other mode.

When error is encountered, current code only flip to other mode one time
(NVMe->FCP) and remain on the last mode.  Driver wrongly assumed target
port does not support PRLI NVMe, instead it was not ready to receive PRLI.

This patch will alternate back and forth on every PRLI failure until login
retry count has depleted or it is succeeded.

Link: https://lore.kernel.org/r/20210817051315.2477-10-njavali@marvell.com


Signed-off-by: default avatarQuinn Tran <qutran@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 2cabf10d
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -2517,6 +2517,8 @@ typedef struct fc_port {
	unsigned int n2n_flag:1;
	unsigned int explicit_logout:1;
	unsigned int prli_pend_timer:1;
	unsigned int do_prli_nvme:1;

	uint8_t nvme_flag;

	uint8_t node_name[WWN_SIZE];
@@ -5351,9 +5353,12 @@ struct sff_8247_a0 {
#define NVME_FCP_TARGET(fcport) \
	(FCP_TYPE(fcport) && NVME_TYPE(fcport)) \

#define NVME_PRIORITY(ha, fcport) \
	(NVME_FCP_TARGET(fcport) && \
	 (ha->fc4_type_priority == FC4_PRIORITY_NVME))

#define NVME_TARGET(ha, fcport) \
	((NVME_FCP_TARGET(fcport) && \
	(ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \
	(fcport->do_prli_nvme || \
	NVME_ONLY_TARGET(fcport)) \

#define PRLI_PHASE(_cls) \
+8 −0
Original line number Diff line number Diff line
@@ -3504,6 +3504,14 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
			fcport->last_rscn_gen = fcport->rscn_gen;
			fcport->fc4_type = rp->fc4type;
			found = true;

			if (fcport->scan_needed) {
				if (NVME_PRIORITY(vha->hw, fcport))
					fcport->do_prli_nvme = 1;
				else
					fcport->do_prli_nvme = 0;
			}

			/*
			 * If device was not a fabric device before.
			 */
+17 −24
Original line number Diff line number Diff line
@@ -2000,6 +2000,7 @@ qla24xx_async_abort_command(srb_t *sp)
static void
qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
{
	struct srb *sp;
	WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
		  ea->data[0]);

@@ -2027,22 +2028,27 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
			break;
		}

		sp = ea->sp;
		ql_dbg(ql_dbg_disc, vha, 0x2118,
		       "%s %d %8phC priority %s, fc4type %x\n",
		       "%s %d %8phC priority %s, fc4type %x prev try %s\n",
		       __func__, __LINE__, ea->fcport->port_name,
		       vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ?
		       "FCP" : "NVMe", ea->fcport->fc4_type);
		       "FCP" : "NVMe", ea->fcport->fc4_type,
		       (sp->u.iocb_cmd.u.logio.flags & SRB_LOGIN_NVME_PRLI) ?
			"NVME" : "FCP");

		if (N2N_TOPO(vha->hw)) {
			if (vha->hw->fc4_type_priority == FC4_PRIORITY_FCP) {
				ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
				ea->fcport->fc4_type |= FS_FC4TYPE_NVME;
		if (NVME_FCP_TARGET(ea->fcport)) {
			if (sp->u.iocb_cmd.u.logio.flags & SRB_LOGIN_NVME_PRLI)
				ea->fcport->do_prli_nvme = 0;
			else
				ea->fcport->do_prli_nvme = 1;
		} else {
				ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
				ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
			ea->fcport->do_prli_nvme = 0;
		}

			if (ea->fcport->n2n_link_reset_cnt < 3) {
		if (N2N_TOPO(vha->hw)) {
			if (ea->fcport->n2n_link_reset_cnt <
			    vha->hw->login_retry_count) {
				ea->fcport->n2n_link_reset_cnt++;
				vha->relogin_jif = jiffies + 2 * HZ;
				/*
@@ -2062,19 +2068,6 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
			 * switch connect. login failed. Take connection down
			 * and allow relogin to retrigger
			 */
			if (NVME_FCP_TARGET(ea->fcport)) {
				ql_dbg(ql_dbg_disc, vha, 0x2118,
				       "%s %d %8phC post %s prli\n",
				       __func__, __LINE__,
				       ea->fcport->port_name,
				       (ea->fcport->fc4_type & FS_FC4TYPE_NVME)
				       ? "NVMe" : "FCP");
				if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
					ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
				else
					ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
			}

			ea->fcport->flags &= ~FCF_ASYNC_SENT;
			ea->fcport->keep_nport_handle = 0;
			ea->fcport->logout_on_delete = 1;
+3 −0
Original line number Diff line number Diff line
@@ -4050,6 +4050,9 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
				fcport->n2n_flag = 1;
				fcport->keep_nport_handle = 1;
				fcport->login_retry = vha->hw->login_retry_count;
				fcport->fc4_type = FS_FC4TYPE_FCP;
				if (vha->flags.nvme_enabled)
					fcport->fc4_type |= FS_FC4TYPE_NVME;

				if (wwn_to_u64(vha->port_name) >
				    wwn_to_u64(fcport->port_name)) {
+5 −0
Original line number Diff line number Diff line
@@ -5184,6 +5184,11 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
			    WWN_SIZE);

			fcport->fc4_type = e->u.new_sess.fc4_type;
			if (NVME_PRIORITY(vha->hw, fcport))
				fcport->do_prli_nvme = 1;
			else
				fcport->do_prli_nvme = 0;

			if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) {
				fcport->dm_login_expire = jiffies +
					QLA_N2N_WAIT_TIME * HZ;