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

Commit cf19c45d authored by Duane Grigsby's avatar Duane Grigsby Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Add command completion for error path



The driver held spinlocks during callbacks for NVME errors which
resulted in a deadlock because recovery LS cmds needed the same lock.

Signed-off-by: default avatarDuane Grigsby <duane.grigsby@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e6373f33
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -427,6 +427,7 @@ struct srb_iocb {
			enum nvmefc_fcp_datadir dir;
			uint32_t dl;
			uint32_t timeout_sec;
			struct	list_head   entry;
		} nvme;
	} u;

@@ -3338,6 +3339,7 @@ struct qla_qpair {
	struct work_struct q_work;
	struct list_head qp_list_elem; /* vha->qp_list */
	struct list_head hints_list;
	struct list_head nvme_done_list;
	uint16_t cpuid;
	struct qla_tgt_counters tgt_counters;
};
+2 −0
Original line number Diff line number Diff line
@@ -865,4 +865,6 @@ void qlt_update_host_map(struct scsi_qla_host *, port_id_t);
void qlt_remove_target_resources(struct qla_hw_data *);
void qlt_clr_qp_table(struct scsi_qla_host *vha);

void qla_nvme_cmpl_io(struct srb_iocb *);

#endif /* _QLA_GBL_H */
+1 −0
Original line number Diff line number Diff line
@@ -7806,6 +7806,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
		qpair->vp_idx = vp_idx;
		qpair->fw_started = ha->flags.fw_started;
		INIT_LIST_HEAD(&qpair->hints_list);
		INIT_LIST_HEAD(&qpair->nvme_done_list);
		qpair->chip_reset = ha->base_qpair->chip_reset;
		qpair->enable_class_2 = ha->base_qpair->enable_class_2;
		qpair->enable_explicit_conf =
+7 −0
Original line number Diff line number Diff line
@@ -759,11 +759,18 @@ static void qla_do_work(struct work_struct *work)
	struct qla_qpair *qpair = container_of(work, struct qla_qpair, q_work);
	struct scsi_qla_host *vha;
	struct qla_hw_data *ha = qpair->hw;
	struct srb_iocb	*nvme, *nxt_nvme;

	spin_lock_irqsave(&qpair->qp_lock, flags);
	vha = pci_get_drvdata(ha->pdev);
	qla24xx_process_response_queue(vha, qpair->rsp);
	spin_unlock_irqrestore(&qpair->qp_lock, flags);

	list_for_each_entry_safe(nvme, nxt_nvme, &qpair->nvme_done_list,
		    u.nvme.entry) {
		list_del_init(&nvme->u.nvme.entry);
		qla_nvme_cmpl_io(nvme);
	}
}

/* create response queue */
+12 −1
Original line number Diff line number Diff line
@@ -154,6 +154,16 @@ static void qla_nvme_sp_ls_done(void *ptr, int res)
	qla2x00_rel_sp(sp);
}

void qla_nvme_cmpl_io(struct srb_iocb *nvme)
{
	srb_t *sp;
	struct nvmefc_fcp_req *fd = nvme->u.nvme.desc;

	sp = container_of(nvme, srb_t, u.iocb_cmd);
	fd->done(fd);
	qla2xxx_rel_qpair_sp(sp->qpair, sp);
}

static void qla_nvme_sp_done(void *ptr, int res)
{
	srb_t *sp = ptr;
@@ -175,7 +185,8 @@ static void qla_nvme_sp_done(void *ptr, int res)
		fd->status = 0;

	fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len;
	fd->done(fd);
	list_add_tail(&nvme->u.nvme.entry, &sp->qpair->nvme_done_list);
	return;
rel:
	qla2xxx_rel_qpair_sp(sp->qpair, sp);
}
Loading