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 | |
| 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>
| -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); |
