Skip to content

Commit 9cd883f

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix session cleanup for N2N
When connection type is N_Port to N_Port (point-to-point), there is a possibilty where initiator will not send PLOGI request and will directly send PRLI. In N2N connection the port has higher port name sends the PLOGI but not allow to send PRLI if is a target mode. Only initiator is allowed to send PRLI. Current driver code deletes old session when it receives PLOGI request. If we will not receive PLOGI request then we will not delete old session and create new session. Add check for N2N with PRLI receive only and trigger cleanup. For this case, the cleanup requires individual cmd abort instead of using implicit logout as a broad stroke flush. Signed-off-by: Krishna Kant <krishna.kant@purestorage.com> Signed-off-by: Alexei Potashnik <alexei@purestorage.com> Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 94d83e3 commit 9cd883f

File tree

7 files changed

+378
-155
lines changed

7 files changed

+378
-155
lines changed

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3508,6 +3508,7 @@ struct qla_hw_data {
35083508

35093509
uint32_t detected_lr_sfp:1;
35103510
uint32_t using_lr_setting:1;
3511+
uint32_t rida_fmt2:1;
35113512
} flags;
35123513

35133514
uint16_t max_exchg;
@@ -4529,6 +4530,16 @@ struct sff_8247_a0 {
45294530
#define USER_CTRL_IRQ(_ha) (ql2xuctrlirq && QLA_TGT_MODE_ENABLED() && \
45304531
(IS_QLA27XX(_ha) || IS_QLA83XX(_ha)))
45314532

4533+
#define SAVE_TOPO(_ha) { \
4534+
if (_ha->current_topology) \
4535+
_ha->prev_topology = _ha->current_topology; \
4536+
}
4537+
4538+
#define N2N_TOPO(ha) \
4539+
((ha->prev_topology == ISP_CFG_N && !ha->current_topology) || \
4540+
ha->current_topology == ISP_CFG_N || \
4541+
!ha->current_topology)
4542+
45324543
#include "qla_target.h"
45334544
#include "qla_gbl.h"
45344545
#include "qla_dbg.h"

drivers/scsi/qla2xxx/qla_fw.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,7 @@ struct vp_rpt_id_entry_24xx {
13921392

13931393
uint8_t port_name[8];
13941394
uint8_t node_name[8];
1395-
uint32_t remote_nport_id;
1395+
uint8_t remote_nport_id[4];
13961396
uint32_t reserved_5;
13971397
} f2;
13981398
} u;

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 102 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,6 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
181181
if (!vha->flags.online)
182182
goto done;
183183

184-
if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
185-
(fcport->fw_login_state == DSC_LS_PLOGI_COMP) ||
186-
(fcport->fw_login_state == DSC_LS_PRLI_PEND))
187-
goto done;
188-
189184
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
190185
if (!sp)
191186
goto done;
@@ -1013,6 +1008,43 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
10131008
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
10141009
} /* gpdb event */
10151010

1011+
1012+
static void qla_chk_n2n_b4_login(struct scsi_qla_host *vha, fc_port_t *fcport)
1013+
{
1014+
u8 login = 0;
1015+
1016+
if (qla_tgt_mode_enabled(vha))
1017+
return;
1018+
1019+
if (qla_dual_mode_enabled(vha)) {
1020+
if (N2N_TOPO(vha->hw)) {
1021+
u64 mywwn, wwn;
1022+
1023+
mywwn = wwn_to_u64(vha->port_name);
1024+
wwn = wwn_to_u64(fcport->port_name);
1025+
if (mywwn > wwn)
1026+
login = 1;
1027+
else if ((fcport->fw_login_state == DSC_LS_PLOGI_COMP)
1028+
&& time_after_eq(jiffies,
1029+
fcport->plogi_nack_done_deadline))
1030+
login = 1;
1031+
} else {
1032+
login = 1;
1033+
}
1034+
} else {
1035+
/* initiator mode */
1036+
login = 1;
1037+
}
1038+
1039+
if (login) {
1040+
ql_dbg(ql_dbg_disc, vha, 0x20bf,
1041+
"%s %d %8phC post login\n",
1042+
__func__, __LINE__, fcport->port_name);
1043+
fcport->disc_state = DSC_LOGIN_PEND;
1044+
qla2x00_post_async_login_work(vha, fcport, NULL);
1045+
}
1046+
}
1047+
10161048
int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
10171049
{
10181050
u16 data[2];
@@ -1037,8 +1069,10 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
10371069
return 0;
10381070

10391071
if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
1040-
if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline))
1072+
if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
1073+
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
10411074
return 0;
1075+
}
10421076
}
10431077

10441078
/* for pure Target Mode. Login will not be initiated */
@@ -1058,11 +1092,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
10581092
__func__, __LINE__, fcport->port_name);
10591093
qla24xx_post_gnl_work(vha, fcport);
10601094
} else {
1061-
ql_dbg(ql_dbg_disc, vha, 0x20bf,
1062-
"%s %d %8phC post login\n",
1063-
__func__, __LINE__, fcport->port_name);
1064-
fcport->disc_state = DSC_LOGIN_PEND;
1065-
qla2x00_post_async_login_work(vha, fcport, NULL);
1095+
qla_chk_n2n_b4_login(vha, fcport);
10661096
}
10671097
break;
10681098

@@ -1074,19 +1104,17 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
10741104
break;
10751105
}
10761106

1077-
ql_dbg(ql_dbg_disc, vha, 0x20cf,
1078-
"%s %d %8phC post login\n",
1079-
__func__, __LINE__, fcport->port_name);
1080-
fcport->disc_state = DSC_LOGIN_PEND;
1081-
qla2x00_post_async_login_work(vha, fcport, NULL);
1107+
qla_chk_n2n_b4_login(vha, fcport);
10821108
break;
10831109

10841110
case DSC_LOGIN_FAILED:
10851111
ql_dbg(ql_dbg_disc, vha, 0x20d0,
10861112
"%s %d %8phC post gidpn\n",
10871113
__func__, __LINE__, fcport->port_name);
1088-
1089-
qla24xx_post_gidpn_work(vha, fcport);
1114+
if (N2N_TOPO(vha->hw))
1115+
qla_chk_n2n_b4_login(vha, fcport);
1116+
else
1117+
qla24xx_post_gidpn_work(vha, fcport);
10901118
break;
10911119

10921120
case DSC_LOGIN_COMPLETE:
@@ -1193,8 +1221,10 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
11931221
return;
11941222

11951223
if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
1196-
if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline))
1224+
if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
1225+
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
11971226
return;
1227+
}
11981228
}
11991229

12001230
if (fcport->flags & FCF_ASYNC_SENT) {
@@ -4434,6 +4464,21 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
44344464

44354465
} else if (ha->current_topology == ISP_CFG_N) {
44364466
clear_bit(RSCN_UPDATE, &flags);
4467+
if (ha->flags.rida_fmt2) {
4468+
/* With Rida Format 2, the login is already triggered.
4469+
* We know who is on the other side of the wire.
4470+
* No need to login to do login to find out or drop into
4471+
* qla2x00_configure_local_loop().
4472+
*/
4473+
clear_bit(LOCAL_LOOP_UPDATE, &flags);
4474+
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
4475+
} else {
4476+
if (qla_tgt_mode_enabled(vha)) {
4477+
/* allow the other side to start the login */
4478+
clear_bit(LOCAL_LOOP_UPDATE, &flags);
4479+
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
4480+
}
4481+
}
44374482
} else if (ha->current_topology == ISP_CFG_NL) {
44384483
clear_bit(RSCN_UPDATE, &flags);
44394484
set_bit(LOCAL_LOOP_UPDATE, &flags);
@@ -4662,6 +4707,10 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
46624707
(uint8_t *)ha->gid_list,
46634708
entries * sizeof(struct gid_list_info));
46644709

4710+
list_for_each_entry(fcport, &vha->vp_fcports, list) {
4711+
fcport->scan_state = QLA_FCPORT_SCAN;
4712+
}
4713+
46654714
/* Allocate temporary fcport for any new fcports discovered. */
46664715
new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
46674716
if (new_fcport == NULL) {
@@ -4672,22 +4721,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
46724721
}
46734722
new_fcport->flags &= ~FCF_FABRIC_DEVICE;
46744723

4675-
/*
4676-
* Mark local devices that were present with FCF_DEVICE_LOST for now.
4677-
*/
4678-
list_for_each_entry(fcport, &vha->vp_fcports, list) {
4679-
if (atomic_read(&fcport->state) == FCS_ONLINE &&
4680-
fcport->port_type != FCT_BROADCAST &&
4681-
(fcport->flags & FCF_FABRIC_DEVICE) == 0) {
4682-
4683-
ql_dbg(ql_dbg_disc, vha, 0x2096,
4684-
"Marking port lost loop_id=0x%04x.\n",
4685-
fcport->loop_id);
4686-
4687-
qla2x00_mark_device_lost(vha, fcport, 0, 0);
4688-
}
4689-
}
4690-
46914724
/* Inititae N2N login. */
46924725
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
46934726
rval = qla24xx_n2n_handle_login(vha, new_fcport);
@@ -4730,6 +4763,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
47304763
new_fcport->d_id.b.area = area;
47314764
new_fcport->d_id.b.al_pa = al_pa;
47324765
new_fcport->loop_id = loop_id;
4766+
new_fcport->scan_state = QLA_FCPORT_FOUND;
47334767

47344768
rval2 = qla2x00_get_port_database(vha, new_fcport, 0);
47354769
if (rval2 != QLA_SUCCESS) {
@@ -4761,13 +4795,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
47614795
fcport->d_id.b24 = new_fcport->d_id.b24;
47624796
memcpy(fcport->node_name, new_fcport->node_name,
47634797
WWN_SIZE);
4764-
4765-
if (!fcport->login_succ) {
4766-
vha->fcport_count++;
4767-
fcport->login_succ = 1;
4768-
fcport->disc_state = DSC_LOGIN_COMPLETE;
4769-
}
4770-
4798+
fcport->scan_state = QLA_FCPORT_FOUND;
47714799
found++;
47724800
break;
47734801
}
@@ -4778,11 +4806,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
47784806

47794807
/* Allocate a new replacement fcport. */
47804808
fcport = new_fcport;
4781-
if (!fcport->login_succ) {
4782-
vha->fcport_count++;
4783-
fcport->login_succ = 1;
4784-
fcport->disc_state = DSC_LOGIN_COMPLETE;
4785-
}
47864809

47874810
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
47884811

@@ -4803,11 +4826,39 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
48034826
/* Base iIDMA settings on HBA port speed. */
48044827
fcport->fp_speed = ha->link_data_rate;
48054828

4806-
qla2x00_update_fcport(vha, fcport);
4807-
48084829
found_devs++;
48094830
}
48104831

4832+
list_for_each_entry(fcport, &vha->vp_fcports, list) {
4833+
if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
4834+
break;
4835+
4836+
if (fcport->scan_state == QLA_FCPORT_SCAN) {
4837+
if ((qla_dual_mode_enabled(vha) ||
4838+
qla_ini_mode_enabled(vha)) &&
4839+
atomic_read(&fcport->state) == FCS_ONLINE) {
4840+
qla2x00_mark_device_lost(vha, fcport,
4841+
ql2xplogiabsentdevice, 0);
4842+
if (fcport->loop_id != FC_NO_LOOP_ID &&
4843+
(fcport->flags & FCF_FCP2_DEVICE) == 0 &&
4844+
fcport->port_type != FCT_INITIATOR &&
4845+
fcport->port_type != FCT_BROADCAST) {
4846+
ql_dbg(ql_dbg_disc, vha, 0x20f0,
4847+
"%s %d %8phC post del sess\n",
4848+
__func__, __LINE__,
4849+
fcport->port_name);
4850+
4851+
qlt_schedule_sess_for_deletion_lock
4852+
(fcport);
4853+
continue;
4854+
}
4855+
}
4856+
}
4857+
4858+
if (fcport->scan_state == QLA_FCPORT_FOUND)
4859+
qla24xx_fcport_handle_login(vha, fcport);
4860+
}
4861+
48114862
cleanup_allocation:
48124863
kfree(new_fcport);
48134864

@@ -6115,6 +6166,8 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
61156166
if (!(IS_P3P_TYPE(ha)))
61166167
ha->isp_ops->reset_chip(vha);
61176168

6169+
SAVE_TOPO(ha);
6170+
ha->flags.rida_fmt2 = 0;
61186171
ha->flags.n2n_ae = 0;
61196172
ha->flags.lip_ae = 0;
61206173
ha->current_topology = 0;

drivers/scsi/qla2xxx/qla_isr.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
809809
break;
810810

811811
case MBA_LOOP_DOWN: /* Loop Down Event */
812+
SAVE_TOPO(ha);
812813
ha->flags.n2n_ae = 0;
813814
ha->flags.lip_ae = 0;
814815
ha->current_topology = 0;
@@ -922,7 +923,6 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
922923
set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
923924
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
924925

925-
ha->flags.gpsc_supported = 1;
926926
vha->flags.management_server_logged_in = 0;
927927
break;
928928

@@ -1060,8 +1060,6 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
10601060
*/
10611061
atomic_set(&vha->loop_state, LOOP_UP);
10621062

1063-
qla2x00_mark_all_devices_lost(vha, 1);
1064-
10651063
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
10661064
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
10671065
set_bit(VP_CONFIG_OK, &vha->vp_flags);

drivers/scsi/qla2xxx/qla_mbx.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3732,6 +3732,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
37323732
unsigned long flags;
37333733
int found;
37343734
port_id_t id;
3735+
struct fc_port *fcport;
37353736

37363737
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
37373738
"Entered %s.\n", __func__);
@@ -3754,7 +3755,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
37543755
"Primary port id %02x%02x%02x.\n",
37553756
rptid_entry->port_id[2], rptid_entry->port_id[1],
37563757
rptid_entry->port_id[0]);
3757-
3758+
ha->current_topology = ISP_CFG_NL;
37583759
qlt_update_host_map(vha, id);
37593760

37603761
} else if (rptid_entry->format == 1) {
@@ -3798,6 +3799,8 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
37983799
return;
37993800
}
38003801

3802+
ha->flags.gpsc_supported = 1;
3803+
ha->current_topology = ISP_CFG_F;
38013804
/* buffer to buffer credit flag */
38023805
vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0;
38033806

@@ -3863,13 +3866,46 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
38633866
rptid_entry->u.f2.port_name);
38643867

38653868
/* N2N. direct connect */
3869+
ha->current_topology = ISP_CFG_N;
3870+
ha->flags.rida_fmt2 = 1;
38663871
vha->d_id.b.domain = rptid_entry->port_id[2];
38673872
vha->d_id.b.area = rptid_entry->port_id[1];
38683873
vha->d_id.b.al_pa = rptid_entry->port_id[0];
38693874

38703875
spin_lock_irqsave(&ha->vport_slock, flags);
38713876
qlt_update_vp_map(vha, SET_AL_PA);
38723877
spin_unlock_irqrestore(&ha->vport_slock, flags);
3878+
3879+
list_for_each_entry(fcport, &vha->vp_fcports, list) {
3880+
fcport->scan_state = QLA_FCPORT_SCAN;
3881+
}
3882+
3883+
fcport = qla2x00_find_fcport_by_wwpn(vha,
3884+
rptid_entry->u.f2.port_name, 1);
3885+
3886+
if (fcport) {
3887+
fcport->plogi_nack_done_deadline = jiffies + HZ;
3888+
fcport->scan_state = QLA_FCPORT_FOUND;
3889+
switch (fcport->disc_state) {
3890+
case DSC_DELETED:
3891+
ql_dbg(ql_dbg_disc, vha, 0x210d,
3892+
"%s %d %8phC login\n",
3893+
__func__, __LINE__, fcport->port_name);
3894+
qla24xx_fcport_handle_login(vha, fcport);
3895+
break;
3896+
case DSC_DELETE_PEND:
3897+
break;
3898+
default:
3899+
qlt_schedule_sess_for_deletion_lock(fcport);
3900+
break;
3901+
}
3902+
} else {
3903+
id.b.al_pa = rptid_entry->u.f2.remote_nport_id[0];
3904+
id.b.area = rptid_entry->u.f2.remote_nport_id[1];
3905+
id.b.domain = rptid_entry->u.f2.remote_nport_id[2];
3906+
qla24xx_post_newsess_work(vha, &id,
3907+
rptid_entry->u.f2.port_name, NULL);
3908+
}
38733909
}
38743910
}
38753911

0 commit comments

Comments
 (0)