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

Commit e326d22a authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Enable Target Multi Queue



Enable Multi Queue for Target mode. At Initiator LUN scan time, each LUN
is assign to a QPair. Each QPair is affinitize to certain CPU. When new
cmd arrives from the wire, the lunid is used to search for qpair. The
qpair's affinitized cpuid will be used to queue up the work element.

Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 82de802a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3245,7 +3245,7 @@ struct req_que {
struct qla_qpair {
	spinlock_t qp_lock;
	atomic_t ref_count;

	uint32_t lun_cnt;
	/*
	 * For qpair 0, qp_lock_ptr will point at hardware_lock due to
	 * legacy code. For other Qpair(s), it will point at qp_lock.
@@ -3275,6 +3275,7 @@ struct qla_qpair {
	struct qla_hw_data *hw;
	struct work_struct q_work;
	struct list_head qp_list_elem; /* vha->qp_list */
	struct list_head hints_list;
	uint16_t cpuid;
};

+3 −0
Original line number Diff line number Diff line
@@ -7623,6 +7623,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
		ha->queue_pair_map[qpair_id] = qpair;
		qpair->id = qpair_id;
		qpair->vp_idx = vp_idx;
		INIT_LIST_HEAD(&qpair->hints_list);

		for (i = 0; i < ha->msix_count; i++) {
			msix = &ha->msix_entries[i];
@@ -7666,6 +7667,8 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
		qpair->req = ha->req_q_map[req_id];
		qpair->rsp->req = qpair->req;
		qpair->rsp->qpair = qpair;
		/* init qpair to this cpu. Will adjust at run time. */
		qla_cpu_update(qpair, smp_processor_id());

		if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
			if (ha->fw_attributes & BIT_4)
+28 −0
Original line number Diff line number Diff line
@@ -324,3 +324,31 @@ qla_is_exch_offld_enabled(struct scsi_qla_host *vha)
	else
		return false;
}

static inline void
qla_cpu_update(struct qla_qpair *qpair, uint16_t cpuid)
{
	qpair->cpuid = cpuid;

	if (!list_empty(&qpair->hints_list)) {
		struct qla_qpair_hint *h;

		list_for_each_entry(h, &qpair->hints_list, hint_elem)
			h->cpuid = qpair->cpuid;
	}
}

static inline struct qla_qpair_hint *
qla_qpair_to_hint(struct qla_tgt *tgt, struct qla_qpair *qpair)
{
	struct qla_qpair_hint *h;
	u16 i;

	for (i = 0; i < tgt->ha->max_qpairs + 1; i++) {
		h = &tgt->qphints[i];
		if (h->qpair == qpair)
			return h;
	}

	return NULL;
}
+13 −8
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/t10-pi.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_bsg_fc.h>
@@ -2761,6 +2762,9 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
	if (!ha->flags.fw_started)
		return;

	if (rsp->qpair->cpuid != smp_processor_id())
		qla_cpu_update(rsp->qpair, smp_processor_id());

	while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
		pkt = (struct sts_entry_24xx *)rsp->ring_ptr;

@@ -3196,10 +3200,10 @@ struct qla_init_msix_entry {
};

static const struct qla_init_msix_entry msix_entries[] = {
	{ "qla2xxx (default)", qla24xx_msix_default },
	{ "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
	{ "qla2xxx (atio_q)", qla83xx_msix_atio_q },
	{ "qla2xxx (qpair_multiq)", qla2xxx_msix_rsp_q },
	{ "default", qla24xx_msix_default },
	{ "rsp_q", qla24xx_msix_rsp_q },
	{ "atio_q", qla83xx_msix_atio_q },
	{ "qpair_multiq", qla2xxx_msix_rsp_q },
};

static const struct qla_init_msix_entry qla82xx_msix_entries[] = {
@@ -3279,7 +3283,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
		qentry->handle = rsp;
		rsp->msix = qentry;
		scnprintf(qentry->name, sizeof(qentry->name),
		    "%s", msix_entries[i].name);
		    "qla2xxx%lu_%s", vha->host_no, msix_entries[i].name);
		if (IS_P3P_TYPE(ha))
			ret = request_irq(qentry->vector,
				qla82xx_msix_entries[i].handler,
@@ -3287,7 +3291,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
		else
			ret = request_irq(qentry->vector,
				msix_entries[i].handler,
				0, msix_entries[i].name, rsp);
				0, qentry->name, rsp);
		if (ret)
			goto msix_register_fail;
		qentry->have_irq = 1;
@@ -3303,11 +3307,12 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
		rsp->msix = qentry;
		qentry->handle = rsp;
		scnprintf(qentry->name, sizeof(qentry->name),
		    "%s", msix_entries[QLA_ATIO_VECTOR].name);
		    "qla2xxx%lu_%s", vha->host_no,
		    msix_entries[QLA_ATIO_VECTOR].name);
		qentry->in_use = 1;
		ret = request_irq(qentry->vector,
			msix_entries[QLA_ATIO_VECTOR].handler,
			0, msix_entries[QLA_ATIO_VECTOR].name, rsp);
			0, qentry->name, rsp);
		qentry->have_irq = 1;
	}

+36 −20
Original line number Diff line number Diff line
@@ -371,30 +371,32 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
		goto fail_rsp_map;
	}

	if (ql2xmqsupport && ha->max_qpairs) {
		ha->queue_pair_map = kcalloc(ha->max_qpairs, sizeof(struct qla_qpair *),
			GFP_KERNEL);
		if (!ha->queue_pair_map) {
			ql_log(ql_log_fatal, vha, 0x0180,
			    "Unable to allocate memory for queue pair ptrs.\n");
			goto fail_qpair_map;
		}
	ha->base_qpair = kzalloc(sizeof(struct qla_qpair), GFP_KERNEL);
	if (ha->base_qpair == NULL) {
		ql_log(ql_log_warn, vha, 0x00e0,
		    "Failed to allocate base queue pair memory.\n");
		goto fail_base_qpair;
	}
		ha->base_qpair->req = req;
		ha->base_qpair->rsp = rsp;
	}

	rsp->qpair = ha->base_qpair;
	rsp->req = req;
	ha->base_qpair->req = req;
	ha->base_qpair->rsp = rsp;
	ha->base_qpair->vha = vha;
	ha->base_qpair->qp_lock_ptr = &ha->hardware_lock;
	ha->queue_pair_map[0] = ha->base_qpair;
	set_bit(0, ha->qpair_qid_map);
	ha->base_qpair->msix = &ha->msix_entries[QLA_MSIX_RSP_Q];
	INIT_LIST_HEAD(&ha->base_qpair->hints_list);
	qla_cpu_update(rsp->qpair, smp_processor_id());

	if (ql2xmqsupport && ha->max_qpairs) {
		ha->queue_pair_map = kcalloc(ha->max_qpairs, sizeof(struct qla_qpair *),
			GFP_KERNEL);
		if (!ha->queue_pair_map) {
			ql_log(ql_log_fatal, vha, 0x0180,
			    "Unable to allocate memory for queue pair ptrs.\n");
			goto fail_qpair_map;
		}
	}

	/*
	 * Make sure we record at least the request and response queue zero in
@@ -2009,7 +2011,7 @@ qla83xx_iospace_config(struct qla_hw_data *ha)
		/* Read MSIX vector size of the board */
		pci_read_config_word(ha->pdev,
		    QLA_83XX_PCI_MSIX_CONTROL, &msix);
		ha->msix_count = msix + 1;
		ha->msix_count = (msix & PCI_MSIX_FLAGS_QSIZE)  + 1;
		/*
		 * By default, driver uses at least two msix vectors
		 * (default & rspq)
@@ -3125,12 +3127,26 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
	    host->can_queue, base_vha->req,
	    base_vha->mgmt_svr_loop_id, host->sg_tablesize);

	if (ha->mqenable && qla_ini_mode_enabled(base_vha)) {
	if (ha->mqenable) {
		bool mq = false;
		bool startit = false;
		ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1);

		if (QLA_TGT_MODE_ENABLED()) {
			mq = true;
			startit = false;
		}

		if ((ql2x_ini_mode == QLA2XXX_INI_MODE_ENABLED) &&
		    shost_use_blk_mq(host)) {
			mq = true;
			startit = true;
		}

		if (mq) {
			/* Create start of day qpairs for Block MQ */
		if (shost_use_blk_mq(host)) {
			for (i = 0; i < ha->max_qpairs; i++)
				qla2xxx_create_qpair(base_vha, 5,  0, true);
				qla2xxx_create_qpair(base_vha, 5, 0, startit);
		}
	}

Loading