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

Commit 67d12733 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.33: Tie parallel I/O queues into separate MSIX vectors



Add fcp_io_channel module attribute to control amount of parallel I/O queues

Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent aa6fbb75
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -695,6 +695,7 @@ struct lpfc_hba {
	uint32_t cfg_fcp_imax;
	uint32_t cfg_fcp_wq_count;
	uint32_t cfg_fcp_eq_count;
	uint32_t cfg_fcp_io_channel;
	uint32_t cfg_sg_seg_cnt;
	uint32_t cfg_prot_sg_seg_cnt;
	uint32_t cfg_sg_dma_buf_size;
+20 −6
Original line number Diff line number Diff line
@@ -3654,7 +3654,7 @@ lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr,
		return -EINVAL;

	phba->cfg_fcp_imax = (uint32_t)val;
	for (i = 0; i < phba->cfg_fcp_eq_count; i += LPFC_MAX_EQ_DELAY)
	for (i = 0; i < phba->cfg_fcp_io_channel; i += LPFC_MAX_EQ_DELAY)
		lpfc_modify_fcp_eq_delay(phba, i);

	return strlen(buf);
@@ -3844,20 +3844,32 @@ LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "

/*
# lpfc_fcp_wq_count: Set the number of fast-path FCP work queues
# This parameter is ignored and will eventually be depricated
#
# Value range is [1,31]. Default value is 4.
# Value range is [1,7]. Default value is 4.
*/
LPFC_ATTR_R(fcp_wq_count, LPFC_FP_WQN_DEF, LPFC_FP_WQN_MIN, LPFC_FP_WQN_MAX,
LPFC_ATTR_R(fcp_wq_count, LPFC_FCP_IO_CHAN_DEF, LPFC_FCP_IO_CHAN_MIN,
	    LPFC_FCP_IO_CHAN_MAX,
	    "Set the number of fast-path FCP work queues, if possible");

/*
# lpfc_fcp_eq_count: Set the number of fast-path FCP event queues
# lpfc_fcp_eq_count: Set the number of FCP EQ/CQ/WQ IO channels
#
# Value range is [1,7]. Default value is 1.
# Value range is [1,7]. Default value is 4.
*/
LPFC_ATTR_R(fcp_eq_count, LPFC_FP_EQN_DEF, LPFC_FP_EQN_MIN, LPFC_FP_EQN_MAX,
LPFC_ATTR_R(fcp_eq_count, LPFC_FCP_IO_CHAN_DEF, LPFC_FCP_IO_CHAN_MIN,
	    LPFC_FCP_IO_CHAN_MAX,
	    "Set the number of fast-path FCP event queues, if possible");

/*
# lpfc_fcp_io_channel: Set the number of FCP EQ/CQ/WQ IO channels
#
# Value range is [1,7]. Default value is 4.
*/
LPFC_ATTR_R(fcp_io_channel, LPFC_FCP_IO_CHAN_DEF, LPFC_FCP_IO_CHAN_MIN,
	    LPFC_FCP_IO_CHAN_MAX,
	    "Set the number of FCP I/O channels");

/*
# lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware.
#       0  = HBA resets disabled
@@ -4002,6 +4014,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
	&dev_attr_lpfc_fcp_imax,
	&dev_attr_lpfc_fcp_wq_count,
	&dev_attr_lpfc_fcp_eq_count,
	&dev_attr_lpfc_fcp_io_channel,
	&dev_attr_lpfc_enable_bg,
	&dev_attr_lpfc_soft_wwnn,
	&dev_attr_lpfc_soft_wwpn,
@@ -4980,6 +4993,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
	lpfc_fcp_wq_count_init(phba, lpfc_fcp_wq_count);
	lpfc_fcp_eq_count_init(phba, lpfc_fcp_eq_count);
	lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel);
	lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
	lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
	lpfc_enable_bg_init(phba, lpfc_enable_bg);
+1 −2
Original line number Diff line number Diff line
@@ -196,8 +196,7 @@ irqreturn_t lpfc_sli_intr_handler(int, void *);
irqreturn_t lpfc_sli_sp_intr_handler(int, void *);
irqreturn_t lpfc_sli_fp_intr_handler(int, void *);
irqreturn_t lpfc_sli4_intr_handler(int, void *);
irqreturn_t lpfc_sli4_sp_intr_handler(int, void *);
irqreturn_t lpfc_sli4_fp_intr_handler(int, void *);
irqreturn_t lpfc_sli4_hba_intr_handler(int, void *);

void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_sli4_swap_str(struct lpfc_hba *, LPFC_MBOXQ_t *);
+26 −52
Original line number Diff line number Diff line
@@ -2013,38 +2013,23 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
	if (*ppos)
		return 0;

	/* Get slow-path event queue information */
	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
			"Slow-path EQ information:\n");
	if (phba->sli4_hba.sp_eq) {
		len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
			"\tEQID[%02d], "
			"QE-COUNT[%04d], QE-SIZE[%04d], "
			"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
			phba->sli4_hba.sp_eq->queue_id,
			phba->sli4_hba.sp_eq->entry_count,
			phba->sli4_hba.sp_eq->entry_size,
			phba->sli4_hba.sp_eq->host_index,
			phba->sli4_hba.sp_eq->hba_index);
	}

	/* Get fast-path event queue information */
	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
			"Fast-path EQ information:\n");
	if (phba->sli4_hba.fp_eq) {
		for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count;
			"HBA EQ information:\n");
	if (phba->sli4_hba.hba_eq) {
		for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_io_channel;
		     fcp_qidx++) {
			if (phba->sli4_hba.fp_eq[fcp_qidx]) {
			if (phba->sli4_hba.hba_eq[fcp_qidx]) {
				len += snprintf(pbuffer+len,
					LPFC_QUE_INFO_GET_BUF_SIZE-len,
				"\tEQID[%02d], "
				"QE-COUNT[%04d], QE-SIZE[%04d], "
				"HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
				phba->sli4_hba.fp_eq[fcp_qidx]->queue_id,
				phba->sli4_hba.fp_eq[fcp_qidx]->entry_count,
				phba->sli4_hba.fp_eq[fcp_qidx]->entry_size,
				phba->sli4_hba.fp_eq[fcp_qidx]->host_index,
				phba->sli4_hba.fp_eq[fcp_qidx]->hba_index);
				phba->sli4_hba.hba_eq[fcp_qidx]->queue_id,
				phba->sli4_hba.hba_eq[fcp_qidx]->entry_count,
				phba->sli4_hba.hba_eq[fcp_qidx]->entry_size,
				phba->sli4_hba.hba_eq[fcp_qidx]->host_index,
				phba->sli4_hba.hba_eq[fcp_qidx]->hba_index);
			}
		}
	}
@@ -2108,7 +2093,7 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
				phba->sli4_hba.fcp_cq[fcp_qidx]->host_index,
				phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index);
			}
		} while (++fcp_qidx < phba->cfg_fcp_eq_count);
		} while (++fcp_qidx < phba->cfg_fcp_io_channel);
		len += snprintf(pbuffer+len,
				LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
	}
@@ -2153,7 +2138,7 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
			"Fast-path FCP WQ information:\n");
	if (phba->sli4_hba.fcp_wq) {
		for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_wq_count;
		for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_io_channel;
		     fcp_qidx++) {
			if (!phba->sli4_hba.fcp_wq[fcp_qidx])
				continue;
@@ -2410,31 +2395,21 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,

	switch (quetp) {
	case LPFC_IDIAG_EQ:
		/* Slow-path event queue */
		if (phba->sli4_hba.sp_eq &&
		    phba->sli4_hba.sp_eq->queue_id == queid) {
			/* Sanity check */
			rc = lpfc_idiag_que_param_check(
					phba->sli4_hba.sp_eq, index, count);
			if (rc)
				goto error_out;
			idiag.ptr_private = phba->sli4_hba.sp_eq;
			goto pass_check;
		}
		/* Fast-path event queue */
		if (phba->sli4_hba.fp_eq) {
			for (qidx = 0; qidx < phba->cfg_fcp_eq_count; qidx++) {
				if (phba->sli4_hba.fp_eq[qidx] &&
				    phba->sli4_hba.fp_eq[qidx]->queue_id ==
		/* HBA event queue */
		if (phba->sli4_hba.hba_eq) {
			for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
				qidx++) {
				if (phba->sli4_hba.hba_eq[qidx] &&
				    phba->sli4_hba.hba_eq[qidx]->queue_id ==
				    queid) {
					/* Sanity check */
					rc = lpfc_idiag_que_param_check(
						phba->sli4_hba.fp_eq[qidx],
						phba->sli4_hba.hba_eq[qidx],
						index, count);
					if (rc)
						goto error_out;
					idiag.ptr_private =
						phba->sli4_hba.fp_eq[qidx];
						phba->sli4_hba.hba_eq[qidx];
					goto pass_check;
				}
			}
@@ -2481,7 +2456,7 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
						phba->sli4_hba.fcp_cq[qidx];
					goto pass_check;
				}
			} while (++qidx < phba->cfg_fcp_eq_count);
			} while (++qidx < phba->cfg_fcp_io_channel);
		}
		goto error_out;
		break;
@@ -2513,7 +2488,8 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
		}
		/* FCP work queue */
		if (phba->sli4_hba.fcp_wq) {
			for (qidx = 0; qidx < phba->cfg_fcp_wq_count; qidx++) {
			for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
				qidx++) {
				if (!phba->sli4_hba.fcp_wq[qidx])
					continue;
				if (phba->sli4_hba.fcp_wq[qidx]->queue_id ==
@@ -4492,7 +4468,7 @@ lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
	lpfc_debug_dump_mbx_wq(phba);
	lpfc_debug_dump_els_wq(phba);

	for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++)
	for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
		lpfc_debug_dump_fcp_wq(phba, fcp_wqidx);

	lpfc_debug_dump_hdr_rq(phba);
@@ -4503,14 +4479,12 @@ lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
	lpfc_debug_dump_mbx_cq(phba);
	lpfc_debug_dump_els_cq(phba);

	for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++)
	for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
		lpfc_debug_dump_fcp_cq(phba, fcp_wqidx);

	/*
	 * Dump Event Queues (EQs)
	 */
	lpfc_debug_dump_sp_eq(phba);

	for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++)
		lpfc_debug_dump_fcp_eq(phba, fcp_wqidx);
	for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
		lpfc_debug_dump_hba_eq(phba, fcp_wqidx);
}
+20 −49
Original line number Diff line number Diff line
@@ -369,7 +369,7 @@ static inline void
lpfc_debug_dump_fcp_wq(struct lpfc_hba *phba, int fcp_wqidx)
{
	/* sanity check */
	if (fcp_wqidx >= phba->cfg_fcp_wq_count)
	if (fcp_wqidx >= phba->cfg_fcp_io_channel)
		return;

	printk(KERN_ERR "FCP WQ: WQ[Idx:%d|Qid:%d]\n",
@@ -391,15 +391,15 @@ lpfc_debug_dump_fcp_cq(struct lpfc_hba *phba, int fcp_wqidx)
	int fcp_cqidx, fcp_cqid;

	/* sanity check */
	if (fcp_wqidx >= phba->cfg_fcp_wq_count)
	if (fcp_wqidx >= phba->cfg_fcp_io_channel)
		return;

	fcp_cqid = phba->sli4_hba.fcp_wq[fcp_wqidx]->assoc_qid;
	for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++)
	for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_io_channel; fcp_cqidx++)
		if (phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id == fcp_cqid)
			break;
	if (phba->intr_type == MSIX) {
		if (fcp_cqidx >= phba->cfg_fcp_eq_count)
		if (fcp_cqidx >= phba->cfg_fcp_io_channel)
			return;
	} else {
		if (fcp_cqidx > 0)
@@ -413,7 +413,7 @@ lpfc_debug_dump_fcp_cq(struct lpfc_hba *phba, int fcp_wqidx)
}

/**
 * lpfc_debug_dump_fcp_eq - dump all entries from a fcp work queue's evt queue
 * lpfc_debug_dump_hba_eq - dump all entries from a fcp work queue's evt queue
 * @phba: Pointer to HBA context object.
 * @fcp_wqidx: Index to a FCP work queue.
 *
@@ -421,36 +421,30 @@ lpfc_debug_dump_fcp_cq(struct lpfc_hba *phba, int fcp_wqidx)
 * associated to the FCP work queue specified by the @fcp_wqidx.
 **/
static inline void
lpfc_debug_dump_fcp_eq(struct lpfc_hba *phba, int fcp_wqidx)
lpfc_debug_dump_hba_eq(struct lpfc_hba *phba, int fcp_wqidx)
{
	struct lpfc_queue *qdesc;
	int fcp_eqidx, fcp_eqid;
	int fcp_cqidx, fcp_cqid;

	/* sanity check */
	if (fcp_wqidx >= phba->cfg_fcp_wq_count)
	if (fcp_wqidx >= phba->cfg_fcp_io_channel)
		return;
	fcp_cqid = phba->sli4_hba.fcp_wq[fcp_wqidx]->assoc_qid;
	for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++)
	for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_io_channel; fcp_cqidx++)
		if (phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id == fcp_cqid)
			break;
	if (phba->intr_type == MSIX) {
		if (fcp_cqidx >= phba->cfg_fcp_eq_count)
		if (fcp_cqidx >= phba->cfg_fcp_io_channel)
			return;
	} else {
		if (fcp_cqidx > 0)
			return;
	}

	if (phba->cfg_fcp_eq_count == 0) {
		fcp_eqidx = -1;
		fcp_eqid = phba->sli4_hba.sp_eq->queue_id;
		qdesc = phba->sli4_hba.sp_eq;
	} else {
	fcp_eqidx = fcp_cqidx;
		fcp_eqid = phba->sli4_hba.fp_eq[fcp_eqidx]->queue_id;
		qdesc = phba->sli4_hba.fp_eq[fcp_eqidx];
	}
	fcp_eqid = phba->sli4_hba.hba_eq[fcp_eqidx]->queue_id;
	qdesc = phba->sli4_hba.hba_eq[fcp_eqidx];

	printk(KERN_ERR "FCP EQ: WQ[Idx:%d|Qid:%d]->CQ[Idx:%d|Qid:%d]->"
		"EQ[Idx:%d|Qid:%d]\n",
@@ -545,25 +539,6 @@ lpfc_debug_dump_mbx_cq(struct lpfc_hba *phba)
	lpfc_debug_dump_q(phba->sli4_hba.mbx_cq);
}

/**
 * lpfc_debug_dump_sp_eq - dump all entries from slow-path event queue
 * @phba: Pointer to HBA context object.
 *
 * This function dumps all entries from the slow-path event queue.
 **/
static inline void
lpfc_debug_dump_sp_eq(struct lpfc_hba *phba)
{
	printk(KERN_ERR "SP EQ: WQ[Qid:%d/Qid:%d]->CQ[Qid:%d/Qid:%d]->"
		"EQ[Qid:%d]:\n",
		phba->sli4_hba.mbx_wq->queue_id,
		phba->sli4_hba.els_wq->queue_id,
		phba->sli4_hba.mbx_cq->queue_id,
		phba->sli4_hba.els_cq->queue_id,
		phba->sli4_hba.sp_eq->queue_id);
	lpfc_debug_dump_q(phba->sli4_hba.sp_eq);
}

/**
 * lpfc_debug_dump_wq_by_id - dump all entries from a work queue by queue id
 * @phba: Pointer to HBA context object.
@@ -577,10 +552,10 @@ lpfc_debug_dump_wq_by_id(struct lpfc_hba *phba, int qid)
{
	int wq_idx;

	for (wq_idx = 0; wq_idx < phba->cfg_fcp_wq_count; wq_idx++)
	for (wq_idx = 0; wq_idx < phba->cfg_fcp_io_channel; wq_idx++)
		if (phba->sli4_hba.fcp_wq[wq_idx]->queue_id == qid)
			break;
	if (wq_idx < phba->cfg_fcp_wq_count) {
	if (wq_idx < phba->cfg_fcp_io_channel) {
		printk(KERN_ERR "FCP WQ[Idx:%d|Qid:%d]\n", wq_idx, qid);
		lpfc_debug_dump_q(phba->sli4_hba.fcp_wq[wq_idx]);
		return;
@@ -647,9 +622,9 @@ lpfc_debug_dump_cq_by_id(struct lpfc_hba *phba, int qid)
	do {
		if (phba->sli4_hba.fcp_cq[cq_idx]->queue_id == qid)
			break;
	} while (++cq_idx < phba->cfg_fcp_eq_count);
	} while (++cq_idx < phba->cfg_fcp_io_channel);

	if (cq_idx < phba->cfg_fcp_eq_count) {
	if (cq_idx < phba->cfg_fcp_io_channel) {
		printk(KERN_ERR "FCP CQ[Idx:%d|Qid:%d]\n", cq_idx, qid);
		lpfc_debug_dump_q(phba->sli4_hba.fcp_cq[cq_idx]);
		return;
@@ -680,21 +655,17 @@ lpfc_debug_dump_eq_by_id(struct lpfc_hba *phba, int qid)
{
	int eq_idx;

	for (eq_idx = 0; eq_idx < phba->cfg_fcp_eq_count; eq_idx++) {
		if (phba->sli4_hba.fp_eq[eq_idx]->queue_id == qid)
	for (eq_idx = 0; eq_idx < phba->cfg_fcp_io_channel; eq_idx++) {
		if (phba->sli4_hba.hba_eq[eq_idx]->queue_id == qid)
			break;
	}

	if (eq_idx < phba->cfg_fcp_eq_count) {
	if (eq_idx < phba->cfg_fcp_io_channel) {
		printk(KERN_ERR "FCP EQ[Idx:%d|Qid:%d]\n", eq_idx, qid);
		lpfc_debug_dump_q(phba->sli4_hba.fp_eq[eq_idx]);
		lpfc_debug_dump_q(phba->sli4_hba.hba_eq[eq_idx]);
		return;
	}

	if (phba->sli4_hba.sp_eq->queue_id == qid) {
		printk(KERN_ERR "SP EQ[|Qid:%d]\n", qid);
		lpfc_debug_dump_q(phba->sli4_hba.sp_eq);
	}
}

void lpfc_debug_dump_all_queues(struct lpfc_hba *);
Loading