Commit ddb95145 authored by Nicholas Bellinger's avatar Nicholas Bellinger

qla2xxx: Fix qlt_lport_register base_vha callback race

This patch closes a race between qlt_lport_register() and
tcm_qla2xxx callback logic by holding qla_tgt_mutex before
making the callback.

In order for this to work, the qlt_add_target() and
qlt_remove_target() code has been changed to avoid the
accessing qla_tgt_mutex + list_[add,del] for NPIV enabled
ports.

This bug introduced in v3.14-rc1 code with commit 49a47f2c.

Cc: Sawan Chandak <sawan.chandak@qlogic.com>
Cc: Quinn Tran <quinn.tran@qlogic.com>
Cc: Saurav Kashyap <saurav.kashyap@qlogic.com>
Cc: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent d6a65fdc
......@@ -4181,6 +4181,9 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha)
tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX;
tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX;
if (base_vha->fc_vport)
return 0;
mutex_lock(&qla_tgt_mutex);
list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist);
mutex_unlock(&qla_tgt_mutex);
......@@ -4194,6 +4197,10 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha)
if (!vha->vha_tgt.qla_tgt)
return 0;
if (vha->fc_vport) {
qlt_release(vha->vha_tgt.qla_tgt);
return 0;
}
mutex_lock(&qla_tgt_mutex);
list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry);
mutex_unlock(&qla_tgt_mutex);
......@@ -4265,6 +4272,12 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn,
spin_unlock_irqrestore(&ha->hardware_lock, flags);
continue;
}
if (tgt->tgt_stop) {
pr_debug("MODE_TARGET in shutdown on qla2xxx(%d)\n",
host->host_no);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
continue;
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (!scsi_host_get(host)) {
......@@ -4279,12 +4292,11 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn,
scsi_host_put(host);
continue;
}
mutex_unlock(&qla_tgt_mutex);
rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn);
if (rc != 0)
scsi_host_put(host);
mutex_unlock(&qla_tgt_mutex);
return rc;
}
mutex_unlock(&qla_tgt_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment