Skip to content

Commit

Permalink
scsi: qla2xxx: Return busy if rport going away
Browse files Browse the repository at this point in the history
This patch adds mechanism to return EBUSY if rport is going away
to prevent exhausting FC-NVMe layer's retry counter.

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>
  • Loading branch information
Darren Trapp authored and Martin K. Petersen committed Mar 21, 2018
1 parent 1763c1f commit 870fe24
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 12 deletions.
1 change: 1 addition & 0 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -2356,6 +2356,7 @@ typedef struct fc_port {
uint8_t nvme_flag;
#define NVME_FLAG_REGISTERED 4
#define NVME_FLAG_DELETING 2
#define NVME_FLAG_RESETTING 1

struct fc_port *conflict;
unsigned char logout_completed;
Expand Down
4 changes: 3 additions & 1 deletion drivers/scsi/qla2xxx/qla_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1910,9 +1910,11 @@ qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
ret = QLA_SUCCESS;
break;

case CS_ABORTED:
case CS_RESET:
case CS_PORT_UNAVAILABLE:
fcport->nvme_flag |= NVME_FLAG_RESETTING;
/* fall through */
case CS_ABORTED:
case CS_PORT_LOGGED_OUT:
case CS_PORT_BUSY:
ql_log(ql_log_warn, fcport->vha, 0x5060,
Expand Down
31 changes: 20 additions & 11 deletions drivers/scsi/qla2xxx/qla_nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
return 0;

INIT_WORK(&fcport->nvme_del_work, qla_nvme_unregister_remote_port);
fcport->nvme_flag &= ~NVME_FLAG_RESETTING;

memset(&req, 0, sizeof(struct nvme_fc_port_info));
req.port_name = wwn_to_u64(fcport->port_name);
Expand Down Expand Up @@ -193,9 +194,9 @@ static void qla_nvme_abort_work(struct work_struct *work)
rval = ha->isp_ops->abort_command(sp);

ql_dbg(ql_dbg_io, fcport->vha, 0x212b,
"%s: %s command for sp=%p on fcport=%p rval=%x\n", __func__,
(rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
sp, fcport, rval);
"%s: %s command for sp=%p, handle=%x on fcport=%p rval=%x\n",
__func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
sp, sp->handle, fcport, rval);
}

static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport,
Expand Down Expand Up @@ -327,7 +328,7 @@ static int qla2x00_start_nvme_mq(srb_t *sp)
}

if (index == req->num_outstanding_cmds) {
rval = -1;
rval = -EBUSY;
goto queuing_error;
}
req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
Expand All @@ -341,7 +342,7 @@ static int qla2x00_start_nvme_mq(srb_t *sp)
req->cnt = req->length - (req->ring_index - cnt);

if (req->cnt < (req_cnt + 2)){
rval = -1;
rval = -EBUSY;
goto queuing_error;
}
}
Expand Down Expand Up @@ -476,14 +477,15 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
fc_port_t *fcport;
struct srb_iocb *nvme;
struct scsi_qla_host *vha;
int rval = QLA_FUNCTION_FAILED;
int rval = -ENODEV;
srb_t *sp;
struct qla_qpair *qpair = hw_queue_handle;
struct nvme_private *priv;
struct qla_nvme_rport *qla_rport = rport->private;

if (!fd) {
ql_log(ql_log_warn, NULL, 0x2134, "NO NVMe FCP request\n");
if (!fd || !qpair) {
ql_log(ql_log_warn, NULL, 0x2134,
"NO NVMe request or Queue Handle\n");
return rval;
}

Expand All @@ -495,13 +497,21 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
}

vha = fcport->vha;
if (!qpair)

/*
* If we know the dev is going away while the transport is still sending
* IO's return busy back to stall the IO Q. This happens when the
* link goes away and fw hasn't notified us yet, but IO's are being
* returned. If the dev comes back quickly we won't exhaust the IO
* retry count at the core.
*/
if (fcport->nvme_flag & NVME_FLAG_RESETTING)
return -EBUSY;

/* Alloc SRB structure */
sp = qla2xxx_get_qpair_sp(qpair, fcport, GFP_ATOMIC);
if (!sp)
return -EIO;
return -EBUSY;

atomic_set(&sp->ref_count, 1);
init_waitqueue_head(&sp->nvme_ls_waitq);
Expand All @@ -519,7 +529,6 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
"qla2x00_start_nvme_mq failed = %d\n", rval);
atomic_dec(&sp->ref_count);
wake_up(&sp->nvme_ls_waitq);
return -EIO;
}

return rval;
Expand Down

0 comments on commit 870fe24

Please sign in to comment.