scsi: qla2xxx: Simpify unregistration of FC-NVMe local/remote ports

Simplified waiting for unregister local/remote FC-NVMe ports
to complete cleanup.

Signed-off-by: Duane Grigsby <duane.grigsby@cavium.com>
Signed-off-by: Darren Trapp <darren.trapp@cavium.com>
Signed-off-by: Anil Gurumurthy <anil.gurumurthy@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
himanshu.madhani@cavium.com 2017-07-21 09:32:26 -07:00 committed by Martin K. Petersen
parent deeae7a69f
commit 5621b0dd74
2 changed files with 12 additions and 53 deletions

View File

@ -2302,8 +2302,7 @@ typedef struct fc_port {
unsigned int login_succ:1; unsigned int login_succ:1;
struct work_struct nvme_del_work; struct work_struct nvme_del_work;
atomic_t nvme_ref_count; struct completion nvme_del_done;
wait_queue_head_t nvme_waitq;
uint32_t nvme_prli_service_param; uint32_t nvme_prli_service_param;
#define NVME_PRLI_SP_CONF BIT_7 #define NVME_PRLI_SP_CONF BIT_7
#define NVME_PRLI_SP_INITIATOR BIT_5 #define NVME_PRLI_SP_INITIATOR BIT_5
@ -4134,8 +4133,7 @@ typedef struct scsi_qla_host {
uint8_t fabric_node_name[WWN_SIZE]; uint8_t fabric_node_name[WWN_SIZE];
struct nvme_fc_local_port *nvme_local_port; struct nvme_fc_local_port *nvme_local_port;
atomic_t nvme_ref_count; struct completion nvme_del_done;
wait_queue_head_t nvme_waitq;
struct list_head nvme_rport_list; struct list_head nvme_rport_list;
atomic_t nvme_active_aen_cnt; atomic_t nvme_active_aen_cnt;
uint16_t nvme_last_rptd_aen; uint16_t nvme_last_rptd_aen;

View File

@ -75,8 +75,6 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
fcport->nvme_remote_port->private = fcport; fcport->nvme_remote_port->private = fcport;
fcport->nvme_flag |= NVME_FLAG_REGISTERED; fcport->nvme_flag |= NVME_FLAG_REGISTERED;
atomic_set(&fcport->nvme_ref_count, 1);
init_waitqueue_head(&fcport->nvme_waitq);
rport->fcport = fcport; rport->fcport = fcport;
list_add_tail(&rport->list, &vha->nvme_rport_list); list_add_tail(&rport->list, &vha->nvme_rport_list);
return 0; return 0;
@ -233,7 +231,6 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
sp->name = "nvme_ls"; sp->name = "nvme_ls";
sp->done = qla_nvme_sp_ls_done; sp->done = qla_nvme_sp_ls_done;
atomic_set(&sp->ref_count, 1); atomic_set(&sp->ref_count, 1);
init_waitqueue_head(&sp->nvme_ls_waitq);
nvme = &sp->u.iocb_cmd; nvme = &sp->u.iocb_cmd;
priv->sp = sp; priv->sp = sp;
priv->fd = fd; priv->fd = fd;
@ -540,12 +537,10 @@ static void qla_nvme_localport_delete(struct nvme_fc_local_port *lport)
{ {
struct scsi_qla_host *vha = lport->private; struct scsi_qla_host *vha = lport->private;
atomic_dec(&vha->nvme_ref_count);
wake_up_all(&vha->nvme_waitq);
ql_log(ql_log_info, vha, 0x210f, ql_log(ql_log_info, vha, 0x210f,
"localport delete of %p completed.\n", vha->nvme_local_port); "localport delete of %p completed.\n", vha->nvme_local_port);
vha->nvme_local_port = NULL; vha->nvme_local_port = NULL;
complete(&vha->nvme_del_done);
} }
static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport) static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
@ -556,8 +551,6 @@ static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
fcport = rport->private; fcport = rport->private;
fcport->nvme_remote_port = NULL; fcport->nvme_remote_port = NULL;
fcport->nvme_flag &= ~NVME_FLAG_REGISTERED; fcport->nvme_flag &= ~NVME_FLAG_REGISTERED;
atomic_dec(&fcport->nvme_ref_count);
wake_up_all(&fcport->nvme_waitq);
list_for_each_entry_safe(r_port, trport, list_for_each_entry_safe(r_port, trport,
&fcport->vha->nvme_rport_list, list) { &fcport->vha->nvme_rport_list, list) {
@ -567,6 +560,7 @@ static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
} }
} }
kfree(r_port); kfree(r_port);
complete(&fcport->nvme_del_done);
ql_log(ql_log_info, fcport->vha, 0x2110, ql_log(ql_log_info, fcport->vha, 0x2110,
"remoteport_delete of %p completed.\n", fcport); "remoteport_delete of %p completed.\n", fcport);
@ -609,12 +603,11 @@ static int qla_nvme_wait_on_command(srb_t *sp)
static int qla_nvme_wait_on_rport_del(fc_port_t *fcport) static int qla_nvme_wait_on_rport_del(fc_port_t *fcport)
{ {
int ret = QLA_SUCCESS; int ret = QLA_SUCCESS;
int timeout;
wait_event_timeout(fcport->nvme_waitq, timeout = wait_for_completion_timeout(&fcport->nvme_del_done,
atomic_read(&fcport->nvme_ref_count), msecs_to_jiffies(2000));
NVME_ABORT_POLLING_PERIOD*HZ); if (!timeout) {
if (atomic_read(&fcport->nvme_ref_count)) {
ret = QLA_FUNCTION_FAILED; ret = QLA_FUNCTION_FAILED;
ql_log(ql_log_info, fcport->vha, 0x2111, ql_log(ql_log_info, fcport->vha, 0x2111,
"timed out waiting for fcport=%p to delete\n", fcport); "timed out waiting for fcport=%p to delete\n", fcport);
@ -633,39 +626,6 @@ void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp)
"nvme_wait_on_comand timed out waiting on sp=%p\n", sp); "nvme_wait_on_comand timed out waiting on sp=%p\n", sp);
} }
static void qla_nvme_abort_all(fc_port_t *fcport)
{
int que, cnt;
unsigned long flags;
srb_t *sp;
struct qla_hw_data *ha = fcport->vha->hw;
struct req_que *req;
spin_lock_irqsave(&ha->hardware_lock, flags);
for (que = 0; que < ha->max_req_queues; que++) {
req = ha->req_q_map[que];
if (!req)
continue;
if (!req->outstanding_cmds)
continue;
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
sp = req->outstanding_cmds[cnt];
if ((sp) && ((sp->type == SRB_NVME_CMD) ||
(sp->type == SRB_NVME_LS)) &&
(sp->fcport == fcport)) {
atomic_inc(&sp->ref_count);
spin_unlock_irqrestore(&ha->hardware_lock,
flags);
qla_nvme_abort(ha, sp);
spin_lock_irqsave(&ha->hardware_lock, flags);
req->outstanding_cmds[cnt] = NULL;
sp->done(sp, 1);
}
}
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
static void qla_nvme_unregister_remote_port(struct work_struct *work) static void qla_nvme_unregister_remote_port(struct work_struct *work)
{ {
struct fc_port *fcport = container_of(work, struct fc_port, struct fc_port *fcport = container_of(work, struct fc_port,
@ -701,12 +661,13 @@ void qla_nvme_delete(struct scsi_qla_host *vha)
ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n", ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n",
__func__, fcport); __func__, fcport);
init_completion(&fcport->nvme_del_done);
nvme_fc_unregister_remoteport(fcport->nvme_remote_port); nvme_fc_unregister_remoteport(fcport->nvme_remote_port);
qla_nvme_wait_on_rport_del(fcport); qla_nvme_wait_on_rport_del(fcport);
qla_nvme_abort_all(fcport);
} }
if (vha->nvme_local_port) { if (vha->nvme_local_port) {
init_completion(&vha->nvme_del_done);
nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port); nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port);
if (nv_ret == 0) if (nv_ret == 0)
ql_log(ql_log_info, vha, 0x2116, ql_log(ql_log_info, vha, 0x2116,
@ -715,6 +676,8 @@ void qla_nvme_delete(struct scsi_qla_host *vha)
else else
ql_log(ql_log_info, vha, 0x2115, ql_log(ql_log_info, vha, 0x2115,
"Unregister of localport failed\n"); "Unregister of localport failed\n");
wait_for_completion_timeout(&vha->nvme_del_done,
msecs_to_jiffies(5000));
} }
} }
@ -755,7 +718,5 @@ void qla_nvme_register_hba(struct scsi_qla_host *vha)
"register_localport failed: ret=%x\n", ret); "register_localport failed: ret=%x\n", ret);
return; return;
} }
atomic_set(&vha->nvme_ref_count, 1);
vha->nvme_local_port->private = vha; vha->nvme_local_port->private = vha;
init_waitqueue_head(&vha->nvme_waitq);
} }