Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddb95145 authored by Nicholas Bellinger's avatar Nicholas Bellinger
Browse files

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
Loading
Loading
Loading
Loading
+14 −2
Original line number Original line Diff line number Diff line
@@ -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_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX;
	tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX;
	tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX;


	if (base_vha->fc_vport)
		return 0;

	mutex_lock(&qla_tgt_mutex);
	mutex_lock(&qla_tgt_mutex);
	list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist);
	list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist);
	mutex_unlock(&qla_tgt_mutex);
	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)
	if (!vha->vha_tgt.qla_tgt)
		return 0;
		return 0;


	if (vha->fc_vport) {
		qlt_release(vha->vha_tgt.qla_tgt);
		return 0;
	}
	mutex_lock(&qla_tgt_mutex);
	mutex_lock(&qla_tgt_mutex);
	list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry);
	list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry);
	mutex_unlock(&qla_tgt_mutex);
	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);
			spin_unlock_irqrestore(&ha->hardware_lock, flags);
			continue;
			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);
		spin_unlock_irqrestore(&ha->hardware_lock, flags);


		if (!scsi_host_get(host)) {
		if (!scsi_host_get(host)) {
@@ -4279,12 +4292,11 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn,
			scsi_host_put(host);
			scsi_host_put(host);
			continue;
			continue;
		}
		}
		mutex_unlock(&qla_tgt_mutex);

		rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn);
		rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn);
		if (rc != 0)
		if (rc != 0)
			scsi_host_put(host);
			scsi_host_put(host);


		mutex_unlock(&qla_tgt_mutex);
		return rc;
		return rc;
	}
	}
	mutex_unlock(&qla_tgt_mutex);
	mutex_unlock(&qla_tgt_mutex);