Skip to content

Commit 9dd9686

Browse files
Darren Trappmartinkpetersen
authored andcommitted
scsi: qla2xxx: Add changes for devloss timeout in driver
Add support for error recovery within devloss timeout, now that FC-NVMe transport support devloss timeout. Signed-off-by: Darren Trapp <darren.trapp@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent dbe1801 commit 9dd9686

File tree

7 files changed

+87
-90
lines changed

7 files changed

+87
-90
lines changed

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,6 +2355,7 @@ typedef struct fc_port {
23552355
#define NVME_PRLI_SP_DISCOVERY BIT_3
23562356
uint8_t nvme_flag;
23572357
#define NVME_FLAG_REGISTERED 4
2358+
#define NVME_FLAG_DELETING 2
23582359

23592360
struct fc_port *conflict;
23602361
unsigned char logout_completed;

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5517,6 +5517,14 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
55175517
break;
55185518
}
55195519

5520+
if (fcport->fc4f_nvme) {
5521+
if (fcport->disc_state == DSC_DELETE_PEND) {
5522+
fcport->disc_state = DSC_GNL;
5523+
vha->fcport_count--;
5524+
fcport->login_succ = 0;
5525+
}
5526+
}
5527+
55205528
if (found) {
55215529
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
55225530
continue;

drivers/scsi/qla2xxx/qla_isr.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,7 +1910,7 @@ qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
19101910
} else {
19111911
switch (le16_to_cpu(sts->comp_status)) {
19121912
case CS_COMPLETE:
1913-
ret = 0;
1913+
ret = QLA_SUCCESS;
19141914
break;
19151915

19161916
case CS_ABORTED:
@@ -1922,7 +1922,8 @@ qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
19221922
"NVME-%s ERR Handling - hdl=%x completion status(%x) resid=%x ox_id=%x\n",
19231923
sp->name, sp->handle, sts->comp_status,
19241924
le32_to_cpu(sts->residual_len), sts->ox_id);
1925-
fd->transferred_length = fd->payload_length;
1925+
fd->transferred_length = 0;
1926+
iocb->u.nvme.rsp_pyld_len = 0;
19261927
ret = QLA_ABORTED;
19271928
break;
19281929

drivers/scsi/qla2xxx/qla_nvme.c

Lines changed: 62 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@ static void qla_nvme_unregister_remote_port(struct work_struct *);
1616

1717
int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
1818
{
19-
struct nvme_rport *rport;
19+
struct qla_nvme_rport *rport;
20+
struct nvme_fc_port_info req;
2021
int ret;
2122

2223
if (!IS_ENABLED(CONFIG_NVME_FC))
2324
return 0;
2425

25-
if (fcport->nvme_flag & NVME_FLAG_REGISTERED)
26-
return 0;
27-
2826
if (!vha->flags.nvme_enabled) {
2927
ql_log(ql_log_info, vha, 0x2100,
3028
"%s: Not registering target since Host NVME is not enabled\n",
@@ -33,38 +31,35 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
3331
}
3432

3533
if (!(fcport->nvme_prli_service_param &
36-
(NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)))
34+
(NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) ||
35+
(fcport->nvme_flag & NVME_FLAG_REGISTERED))
3736
return 0;
3837

3938
INIT_WORK(&fcport->nvme_del_work, qla_nvme_unregister_remote_port);
40-
rport = kzalloc(sizeof(*rport), GFP_KERNEL);
41-
if (!rport) {
42-
ql_log(ql_log_warn, vha, 0x2101,
43-
"%s: unable to alloc memory\n", __func__);
44-
return -ENOMEM;
45-
}
4639

47-
rport->req.port_name = wwn_to_u64(fcport->port_name);
48-
rport->req.node_name = wwn_to_u64(fcport->node_name);
49-
rport->req.port_role = 0;
40+
memset(&req, 0, sizeof(struct nvme_fc_port_info));
41+
req.port_name = wwn_to_u64(fcport->port_name);
42+
req.node_name = wwn_to_u64(fcport->node_name);
43+
req.port_role = 0;
44+
req.dev_loss_tmo = NVME_FC_DEV_LOSS_TMO;
5045

5146
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR)
52-
rport->req.port_role = FC_PORT_ROLE_NVME_INITIATOR;
47+
req.port_role = FC_PORT_ROLE_NVME_INITIATOR;
5348

5449
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_TARGET)
55-
rport->req.port_role |= FC_PORT_ROLE_NVME_TARGET;
50+
req.port_role |= FC_PORT_ROLE_NVME_TARGET;
5651

5752
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_DISCOVERY)
58-
rport->req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY;
53+
req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY;
5954

60-
rport->req.port_id = fcport->d_id.b24;
55+
req.port_id = fcport->d_id.b24;
6156

6257
ql_log(ql_log_info, vha, 0x2102,
6358
"%s: traddr=nn-0x%016llx:pn-0x%016llx PortID:%06x\n",
64-
__func__, rport->req.node_name, rport->req.port_name,
65-
rport->req.port_id);
59+
__func__, req.node_name, req.port_name,
60+
req.port_id);
6661

67-
ret = nvme_fc_register_remoteport(vha->nvme_local_port, &rport->req,
62+
ret = nvme_fc_register_remoteport(vha->nvme_local_port, &req,
6863
&fcport->nvme_remote_port);
6964
if (ret) {
7065
ql_log(ql_log_warn, vha, 0x212e,
@@ -73,10 +68,11 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
7368
return ret;
7469
}
7570

76-
fcport->nvme_remote_port->private = fcport;
77-
fcport->nvme_flag |= NVME_FLAG_REGISTERED;
71+
rport = fcport->nvme_remote_port->private;
7872
rport->fcport = fcport;
7973
list_add_tail(&rport->list, &vha->nvme_rport_list);
74+
75+
fcport->nvme_flag |= NVME_FLAG_REGISTERED;
8076
return 0;
8177
}
8278

@@ -174,26 +170,23 @@ static void qla_nvme_sp_done(void *ptr, int res)
174170
if (!atomic_dec_and_test(&sp->ref_count))
175171
return;
176172

177-
if (!(sp->fcport->nvme_flag & NVME_FLAG_REGISTERED))
178-
goto rel;
179-
180-
if (unlikely(res == QLA_FUNCTION_FAILED))
181-
fd->status = NVME_SC_INTERNAL;
182-
else
173+
if (res == QLA_SUCCESS)
183174
fd->status = 0;
175+
else
176+
fd->status = NVME_SC_INTERNAL;
184177

185178
fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len;
186179
list_add_tail(&nvme->u.nvme.entry, &sp->qpair->nvme_done_list);
180+
187181
return;
188-
rel:
189-
qla2xxx_rel_qpair_sp(sp->qpair, sp);
190182
}
191183

192184
static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport,
193185
struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd)
194186
{
195187
struct nvme_private *priv = fd->private;
196-
fc_port_t *fcport = rport->private;
188+
struct qla_nvme_rport *qla_rport = rport->private;
189+
fc_port_t *fcport = qla_rport->fcport;
197190
srb_t *sp = priv->sp;
198191
int rval;
199192
struct qla_hw_data *ha = fcport->vha->hw;
@@ -218,17 +211,15 @@ static void qla_nvme_ls_complete(struct work_struct *work)
218211
static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
219212
struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd)
220213
{
221-
fc_port_t *fcport = rport->private;
214+
struct qla_nvme_rport *qla_rport = rport->private;
215+
fc_port_t *fcport = qla_rport->fcport;
222216
struct srb_iocb *nvme;
223217
struct nvme_private *priv = fd->private;
224218
struct scsi_qla_host *vha;
225219
int rval = QLA_FUNCTION_FAILED;
226220
struct qla_hw_data *ha;
227221
srb_t *sp;
228222

229-
if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))
230-
return rval;
231-
232223
vha = fcport->vha;
233224
ha = vha->hw;
234225
/* Alloc SRB structure */
@@ -275,7 +266,8 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport,
275266
struct nvme_private *priv = fd->private;
276267
srb_t *sp = priv->sp;
277268
int rval;
278-
fc_port_t *fcport = rport->private;
269+
struct qla_nvme_rport *qla_rport = rport->private;
270+
fc_port_t *fcport = qla_rport->fcport;
279271
struct qla_hw_data *ha = fcport->vha->hw;
280272

281273
rval = ha->isp_ops->abort_command(sp);
@@ -288,11 +280,10 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport,
288280

289281
static void qla_nvme_poll(struct nvme_fc_local_port *lport, void *hw_queue_handle)
290282
{
291-
struct scsi_qla_host *vha = lport->private;
292-
unsigned long flags;
293283
struct qla_qpair *qpair = hw_queue_handle;
284+
unsigned long flags;
285+
struct scsi_qla_host *vha = lport->private;
294286

295-
/* Acquire ring specific lock */
296287
spin_lock_irqsave(&qpair->qp_lock, flags);
297288
qla24xx_process_response_queue(vha, qpair->rsp);
298289
spin_unlock_irqrestore(&qpair->qp_lock, flags);
@@ -490,21 +481,22 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
490481
srb_t *sp;
491482
struct qla_qpair *qpair = hw_queue_handle;
492483
struct nvme_private *priv;
484+
struct qla_nvme_rport *qla_rport = rport->private;
493485

494486
if (!fd) {
495487
ql_log(ql_log_warn, NULL, 0x2134, "NO NVMe FCP request\n");
496488
return rval;
497489
}
498490

499491
priv = fd->private;
500-
fcport = rport->private;
492+
fcport = qla_rport->fcport;
501493
if (!fcport) {
502494
ql_log(ql_log_warn, NULL, 0x210e, "No fcport ptr\n");
503495
return rval;
504496
}
505497

506498
vha = fcport->vha;
507-
if ((!qpair) || (!(fcport->nvme_flag & NVME_FLAG_REGISTERED)))
499+
if (!qpair)
508500
return -EBUSY;
509501

510502
/* Alloc SRB structure */
@@ -547,22 +539,27 @@ static void qla_nvme_localport_delete(struct nvme_fc_local_port *lport)
547539
static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
548540
{
549541
fc_port_t *fcport;
550-
struct nvme_rport *r_port, *trport;
542+
struct qla_nvme_rport *qla_rport = rport->private, *trport;
551543

552-
fcport = rport->private;
544+
fcport = qla_rport->fcport;
553545
fcport->nvme_remote_port = NULL;
554546
fcport->nvme_flag &= ~NVME_FLAG_REGISTERED;
555547

556-
list_for_each_entry_safe(r_port, trport,
548+
list_for_each_entry_safe(qla_rport, trport,
557549
&fcport->vha->nvme_rport_list, list) {
558-
if (r_port->fcport == fcport) {
559-
list_del(&r_port->list);
550+
if (qla_rport->fcport == fcport) {
551+
list_del(&qla_rport->list);
560552
break;
561553
}
562554
}
563-
kfree(r_port);
564555
complete(&fcport->nvme_del_done);
565556

557+
if (!test_bit(UNLOADING, &fcport->vha->dpc_flags)) {
558+
INIT_WORK(&fcport->free_work, qlt_free_session_done);
559+
schedule_work(&fcport->free_work);
560+
}
561+
562+
fcport->nvme_flag &= ~(NVME_FLAG_REGISTERED | NVME_FLAG_DELETING);
566563
ql_log(ql_log_info, fcport->vha, 0x2110,
567564
"remoteport_delete of %p completed.\n", fcport);
568565
}
@@ -582,7 +579,7 @@ static struct nvme_fc_port_template qla_nvme_fc_transport = {
582579
.max_dif_sgl_segments = 64,
583580
.dma_boundary = 0xFFFFFFFF,
584581
.local_priv_sz = 8,
585-
.remote_priv_sz = 0,
582+
.remote_priv_sz = sizeof(struct qla_nvme_rport),
586583
.lsrqst_priv_sz = sizeof(struct nvme_private),
587584
.fcprqst_priv_sz = sizeof(struct nvme_private),
588585
};
@@ -601,22 +598,6 @@ static int qla_nvme_wait_on_command(srb_t *sp)
601598
return ret;
602599
}
603600

604-
static int qla_nvme_wait_on_rport_del(fc_port_t *fcport)
605-
{
606-
int ret = QLA_SUCCESS;
607-
int timeout;
608-
609-
timeout = wait_for_completion_timeout(&fcport->nvme_del_done,
610-
msecs_to_jiffies(2000));
611-
if (!timeout) {
612-
ret = QLA_FUNCTION_FAILED;
613-
ql_log(ql_log_info, fcport->vha, 0x2111,
614-
"timed out waiting for fcport=%p to delete\n", fcport);
615-
}
616-
617-
return ret;
618-
}
619-
620601
void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp)
621602
{
622603
int rval;
@@ -631,59 +612,60 @@ static void qla_nvme_unregister_remote_port(struct work_struct *work)
631612
{
632613
struct fc_port *fcport = container_of(work, struct fc_port,
633614
nvme_del_work);
634-
struct nvme_rport *rport, *trport;
615+
struct qla_nvme_rport *qla_rport, *trport;
635616

636617
if (!IS_ENABLED(CONFIG_NVME_FC))
637618
return;
638619

639620
ql_log(ql_log_warn, NULL, 0x2112,
640621
"%s: unregister remoteport on %p\n",__func__, fcport);
641622

642-
list_for_each_entry_safe(rport, trport,
623+
list_for_each_entry_safe(qla_rport, trport,
643624
&fcport->vha->nvme_rport_list, list) {
644-
if (rport->fcport == fcport) {
625+
if (qla_rport->fcport == fcport) {
645626
ql_log(ql_log_info, fcport->vha, 0x2113,
646627
"%s: fcport=%p\n", __func__, fcport);
647628
init_completion(&fcport->nvme_del_done);
648629
nvme_fc_unregister_remoteport(
649630
fcport->nvme_remote_port);
650-
qla_nvme_wait_on_rport_del(fcport);
631+
wait_for_completion(&fcport->nvme_del_done);
632+
break;
651633
}
652634
}
653635
}
654636

655637
void qla_nvme_delete(struct scsi_qla_host *vha)
656638
{
657-
struct nvme_rport *rport, *trport;
639+
struct qla_nvme_rport *qla_rport, *trport;
658640
fc_port_t *fcport;
659641
int nv_ret;
660642

661643
if (!IS_ENABLED(CONFIG_NVME_FC))
662644
return;
663645

664-
list_for_each_entry_safe(rport, trport, &vha->nvme_rport_list, list) {
665-
fcport = rport->fcport;
646+
list_for_each_entry_safe(qla_rport, trport,
647+
&vha->nvme_rport_list, list) {
648+
fcport = qla_rport->fcport;
666649

667650
ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n",
668651
__func__, fcport);
669652

670653
init_completion(&fcport->nvme_del_done);
671654
nvme_fc_unregister_remoteport(fcport->nvme_remote_port);
672-
qla_nvme_wait_on_rport_del(fcport);
655+
wait_for_completion(&fcport->nvme_del_done);
673656
}
674657

675658
if (vha->nvme_local_port) {
676659
init_completion(&vha->nvme_del_done);
660+
ql_log(ql_log_info, vha, 0x2116,
661+
"unregister localport=%p\n",
662+
vha->nvme_local_port);
677663
nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port);
678-
if (nv_ret == 0)
679-
ql_log(ql_log_info, vha, 0x2116,
680-
"unregistered localport=%p\n",
681-
vha->nvme_local_port);
682-
else
664+
if (nv_ret)
683665
ql_log(ql_log_info, vha, 0x2115,
684666
"Unregister of localport failed\n");
685-
wait_for_completion_timeout(&vha->nvme_del_done,
686-
msecs_to_jiffies(5000));
667+
else
668+
wait_for_completion(&vha->nvme_del_done);
687669
}
688670
}
689671

drivers/scsi/qla2xxx/qla_nvme.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
#include "qla_def.h"
1616

17+
/* default dev loss time (seconds) before transport tears down ctrl */
18+
#define NVME_FC_DEV_LOSS_TMO 30
19+
1720
#define NVME_ATIO_CMD_OFF 32
1821
#define NVME_FIRST_PACKET_CMDLEN (64 - NVME_ATIO_CMD_OFF)
1922
#define Q2T_NVME_NUM_TAGS 2048
@@ -31,8 +34,7 @@ struct nvme_private {
3134
int comp_status;
3235
};
3336

34-
struct nvme_rport {
35-
struct nvme_fc_port_info req;
37+
struct qla_nvme_rport {
3638
struct list_head list;
3739
struct fc_port *fcport;
3840
};

0 commit comments

Comments
 (0)