diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-02-19 20:51:25 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-02-20 16:01:17 -0500 |
commit | ddb95145a38eb37b236d4e00f43a75d067922dda (patch) | |
tree | 81a67c0febfeae8f71e8ca06e21dbb6f6aea9aa3 /drivers/scsi/qla2xxx/qla_target.c | |
parent | d6a65fdc8903e632aa7bf86ee0f61a73969371f6 (diff) |
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 49a47f2.
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: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_target.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 2eb97d7e8d12..ea3eaef3f81b 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -4181,6 +4181,9 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) | |||
4181 | tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; | 4181 | tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; |
4182 | tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; | 4182 | tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; |
4183 | 4183 | ||
4184 | if (base_vha->fc_vport) | ||
4185 | return 0; | ||
4186 | |||
4184 | mutex_lock(&qla_tgt_mutex); | 4187 | mutex_lock(&qla_tgt_mutex); |
4185 | list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); | 4188 | list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); |
4186 | mutex_unlock(&qla_tgt_mutex); | 4189 | mutex_unlock(&qla_tgt_mutex); |
@@ -4194,6 +4197,10 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha) | |||
4194 | if (!vha->vha_tgt.qla_tgt) | 4197 | if (!vha->vha_tgt.qla_tgt) |
4195 | return 0; | 4198 | return 0; |
4196 | 4199 | ||
4200 | if (vha->fc_vport) { | ||
4201 | qlt_release(vha->vha_tgt.qla_tgt); | ||
4202 | return 0; | ||
4203 | } | ||
4197 | mutex_lock(&qla_tgt_mutex); | 4204 | mutex_lock(&qla_tgt_mutex); |
4198 | list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry); | 4205 | list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry); |
4199 | mutex_unlock(&qla_tgt_mutex); | 4206 | mutex_unlock(&qla_tgt_mutex); |
@@ -4265,6 +4272,12 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, | |||
4265 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4272 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4266 | continue; | 4273 | continue; |
4267 | } | 4274 | } |
4275 | if (tgt->tgt_stop) { | ||
4276 | pr_debug("MODE_TARGET in shutdown on qla2xxx(%d)\n", | ||
4277 | host->host_no); | ||
4278 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4279 | continue; | ||
4280 | } | ||
4268 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4281 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4269 | 4282 | ||
4270 | if (!scsi_host_get(host)) { | 4283 | if (!scsi_host_get(host)) { |
@@ -4279,12 +4292,11 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, | |||
4279 | scsi_host_put(host); | 4292 | scsi_host_put(host); |
4280 | continue; | 4293 | continue; |
4281 | } | 4294 | } |
4282 | mutex_unlock(&qla_tgt_mutex); | ||
4283 | |||
4284 | rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn); | 4295 | rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn); |
4285 | if (rc != 0) | 4296 | if (rc != 0) |
4286 | scsi_host_put(host); | 4297 | scsi_host_put(host); |
4287 | 4298 | ||
4299 | mutex_unlock(&qla_tgt_mutex); | ||
4288 | return rc; | 4300 | return rc; |
4289 | } | 4301 | } |
4290 | mutex_unlock(&qla_tgt_mutex); | 4302 | mutex_unlock(&qla_tgt_mutex); |