[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: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
aa6fbb757a
commit
67d1273385
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4921,16 +4921,15 @@ lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba)
|
|||
lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
|
||||
fcp_eqidx = 0;
|
||||
if (phba->sli4_hba.fcp_cq) {
|
||||
do
|
||||
do {
|
||||
lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[fcp_eqidx],
|
||||
LPFC_QUEUE_REARM);
|
||||
while (++fcp_eqidx < phba->cfg_fcp_eq_count);
|
||||
} while (++fcp_eqidx < phba->cfg_fcp_io_channel);
|
||||
}
|
||||
lpfc_sli4_eq_release(phba->sli4_hba.sp_eq, LPFC_QUEUE_REARM);
|
||||
if (phba->sli4_hba.fp_eq) {
|
||||
for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count;
|
||||
if (phba->sli4_hba.hba_eq) {
|
||||
for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_io_channel;
|
||||
fcp_eqidx++)
|
||||
lpfc_sli4_eq_release(phba->sli4_hba.fp_eq[fcp_eqidx],
|
||||
lpfc_sli4_eq_release(phba->sli4_hba.hba_eq[fcp_eqidx],
|
||||
LPFC_QUEUE_REARM);
|
||||
}
|
||||
}
|
||||
|
@ -7818,7 +7817,7 @@ lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba)
|
|||
int i;
|
||||
|
||||
i = atomic_add_return(1, &phba->fcp_qidx);
|
||||
i = (i % phba->cfg_fcp_wq_count);
|
||||
i = (i % phba->cfg_fcp_io_channel);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -8727,7 +8726,7 @@ lpfc_sli_setup(struct lpfc_hba *phba)
|
|||
|
||||
psli->num_rings = MAX_SLI3_CONFIGURED_RINGS;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
psli->num_rings += phba->cfg_fcp_eq_count;
|
||||
psli->num_rings += phba->cfg_fcp_io_channel;
|
||||
psli->sli_flag = 0;
|
||||
psli->fcp_ring = LPFC_FCP_RING;
|
||||
psli->next_ring = LPFC_FCP_NEXT_RING;
|
||||
|
@ -11468,31 +11467,18 @@ lpfc_sli4_sp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
|
|||
*
|
||||
**/
|
||||
static void
|
||||
lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe)
|
||||
lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
|
||||
struct lpfc_queue *speq)
|
||||
{
|
||||
struct lpfc_queue *cq = NULL, *childq, *speq;
|
||||
struct lpfc_queue *cq = NULL, *childq;
|
||||
struct lpfc_cqe *cqe;
|
||||
bool workposted = false;
|
||||
int ecount = 0;
|
||||
uint16_t cqid;
|
||||
|
||||
if (bf_get_le32(lpfc_eqe_major_code, eqe) != 0) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"0359 Not a valid slow-path completion "
|
||||
"event: majorcode=x%x, minorcode=x%x\n",
|
||||
bf_get_le32(lpfc_eqe_major_code, eqe),
|
||||
bf_get_le32(lpfc_eqe_minor_code, eqe));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the reference to the corresponding CQ */
|
||||
cqid = bf_get_le32(lpfc_eqe_resource_id, eqe);
|
||||
|
||||
/* Search for completion queue pointer matching this cqid */
|
||||
speq = phba->sli4_hba.sp_eq;
|
||||
/* sanity check on queue memory */
|
||||
if (unlikely(!speq))
|
||||
return;
|
||||
list_for_each_entry(childq, &speq->child_list, list) {
|
||||
if (childq->queue_id == cqid) {
|
||||
cq = childq;
|
||||
|
@ -11711,7 +11697,7 @@ lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
|
|||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_fp_handle_eqe - Process a fast-path event queue entry
|
||||
* lpfc_sli4_hba_handle_eqe - Process a fast-path event queue entry
|
||||
* @phba: Pointer to HBA context object.
|
||||
* @eqe: Pointer to fast-path event queue entry.
|
||||
*
|
||||
|
@ -11723,8 +11709,8 @@ lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
|
|||
* completion queue, and then return.
|
||||
**/
|
||||
static void
|
||||
lpfc_sli4_fp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
|
||||
uint32_t fcp_cqidx)
|
||||
lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
|
||||
uint32_t qidx)
|
||||
{
|
||||
struct lpfc_queue *cq;
|
||||
struct lpfc_cqe *cqe;
|
||||
|
@ -11734,30 +11720,38 @@ lpfc_sli4_fp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
|
|||
|
||||
if (unlikely(bf_get_le32(lpfc_eqe_major_code, eqe) != 0)) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"0366 Not a valid fast-path completion "
|
||||
"0366 Not a valid completion "
|
||||
"event: majorcode=x%x, minorcode=x%x\n",
|
||||
bf_get_le32(lpfc_eqe_major_code, eqe),
|
||||
bf_get_le32(lpfc_eqe_minor_code, eqe));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the reference to the corresponding CQ */
|
||||
cqid = bf_get_le32(lpfc_eqe_resource_id, eqe);
|
||||
|
||||
/* Check if this is a Slow path event */
|
||||
if (unlikely(cqid != phba->sli4_hba.fcp_cq_map[qidx])) {
|
||||
lpfc_sli4_sp_handle_eqe(phba, eqe,
|
||||
phba->sli4_hba.hba_eq[qidx]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlikely(!phba->sli4_hba.fcp_cq)) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
|
||||
"3146 Fast-path completion queues "
|
||||
"does not exist\n");
|
||||
return;
|
||||
}
|
||||
cq = phba->sli4_hba.fcp_cq[fcp_cqidx];
|
||||
cq = phba->sli4_hba.fcp_cq[qidx];
|
||||
if (unlikely(!cq)) {
|
||||
if (phba->sli.sli_flag & LPFC_SLI_ACTIVE)
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"0367 Fast-path completion queue "
|
||||
"(%d) does not exist\n", fcp_cqidx);
|
||||
"(%d) does not exist\n", qidx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the reference to the corresponding CQ */
|
||||
cqid = bf_get_le32(lpfc_eqe_resource_id, eqe);
|
||||
if (unlikely(cqid != cq->queue_id)) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"0368 Miss-matched fast-path completion "
|
||||
|
@ -11805,93 +11799,7 @@ lpfc_sli4_eq_flush(struct lpfc_hba *phba, struct lpfc_queue *eq)
|
|||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_sp_intr_handler - Slow-path interrupt handler to SLI-4 device
|
||||
* @irq: Interrupt number.
|
||||
* @dev_id: The device context pointer.
|
||||
*
|
||||
* This function is directly called from the PCI layer as an interrupt
|
||||
* service routine when device with SLI-4 interface spec is enabled with
|
||||
* MSI-X multi-message interrupt mode and there are slow-path events in
|
||||
* the HBA. However, when the device is enabled with either MSI or Pin-IRQ
|
||||
* interrupt mode, this function is called as part of the device-level
|
||||
* interrupt handler. When the PCI slot is in error recovery or the HBA is
|
||||
* undergoing initialization, the interrupt handler will not process the
|
||||
* interrupt. The link attention and ELS ring attention events are handled
|
||||
* by the worker thread. The interrupt handler signals the worker thread
|
||||
* and returns for these events. This function is called without any lock
|
||||
* held. It gets the hbalock to access and update SLI data structures.
|
||||
*
|
||||
* This function returns IRQ_HANDLED when interrupt is handled else it
|
||||
* returns IRQ_NONE.
|
||||
**/
|
||||
irqreturn_t
|
||||
lpfc_sli4_sp_intr_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct lpfc_hba *phba;
|
||||
struct lpfc_queue *speq;
|
||||
struct lpfc_eqe *eqe;
|
||||
unsigned long iflag;
|
||||
int ecount = 0;
|
||||
|
||||
/*
|
||||
* Get the driver's phba structure from the dev_id
|
||||
*/
|
||||
phba = (struct lpfc_hba *)dev_id;
|
||||
|
||||
if (unlikely(!phba))
|
||||
return IRQ_NONE;
|
||||
|
||||
/* Get to the EQ struct associated with this vector */
|
||||
speq = phba->sli4_hba.sp_eq;
|
||||
if (unlikely(!speq))
|
||||
return IRQ_NONE;
|
||||
|
||||
/* Check device state for handling interrupt */
|
||||
if (unlikely(lpfc_intr_state_check(phba))) {
|
||||
speq->EQ_badstate++;
|
||||
/* Check again for link_state with lock held */
|
||||
spin_lock_irqsave(&phba->hbalock, iflag);
|
||||
if (phba->link_state < LPFC_LINK_DOWN)
|
||||
/* Flush, clear interrupt, and rearm the EQ */
|
||||
lpfc_sli4_eq_flush(phba, speq);
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflag);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process all the event on FCP slow-path EQ
|
||||
*/
|
||||
while ((eqe = lpfc_sli4_eq_get(speq))) {
|
||||
lpfc_sli4_sp_handle_eqe(phba, eqe);
|
||||
if (!(++ecount % speq->entry_repost))
|
||||
lpfc_sli4_eq_release(speq, LPFC_QUEUE_NOARM);
|
||||
speq->EQ_processed++;
|
||||
}
|
||||
|
||||
/* Track the max number of EQEs processed in 1 intr */
|
||||
if (ecount > speq->EQ_max_eqe)
|
||||
speq->EQ_max_eqe = ecount;
|
||||
|
||||
/* Always clear and re-arm the slow-path EQ */
|
||||
lpfc_sli4_eq_release(speq, LPFC_QUEUE_REARM);
|
||||
|
||||
/* Catch the no cq entry condition */
|
||||
if (unlikely(ecount == 0)) {
|
||||
speq->EQ_no_entry++;
|
||||
if (phba->intr_type == MSIX)
|
||||
/* MSI-X treated interrupt served as no EQ share INT */
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
|
||||
"0357 MSI-X interrupt with no EQE\n");
|
||||
else
|
||||
/* Non MSI-X treated on interrupt as EQ share INT */
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
} /* lpfc_sli4_sp_intr_handler */
|
||||
|
||||
/**
|
||||
* lpfc_sli4_fp_intr_handler - Fast-path interrupt handler to SLI-4 device
|
||||
* lpfc_sli4_hba_intr_handler - HBA interrupt handler to SLI-4 device
|
||||
* @irq: Interrupt number.
|
||||
* @dev_id: The device context pointer.
|
||||
*
|
||||
|
@ -11908,11 +11816,16 @@ lpfc_sli4_sp_intr_handler(int irq, void *dev_id)
|
|||
* the FCP EQ to FCP CQ are one-to-one map such that the FCP EQ index is
|
||||
* equal to that of FCP CQ index.
|
||||
*
|
||||
* The link attention and ELS ring attention events are handled
|
||||
* by the worker thread. The interrupt handler signals the worker thread
|
||||
* and returns for these events. This function is called without any lock
|
||||
* held. It gets the hbalock to access and update SLI data structures.
|
||||
*
|
||||
* This function returns IRQ_HANDLED when interrupt is handled else it
|
||||
* returns IRQ_NONE.
|
||||
**/
|
||||
irqreturn_t
|
||||
lpfc_sli4_fp_intr_handler(int irq, void *dev_id)
|
||||
lpfc_sli4_hba_intr_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct lpfc_hba *phba;
|
||||
struct lpfc_fcp_eq_hdl *fcp_eq_hdl;
|
||||
|
@ -11929,11 +11842,11 @@ lpfc_sli4_fp_intr_handler(int irq, void *dev_id)
|
|||
|
||||
if (unlikely(!phba))
|
||||
return IRQ_NONE;
|
||||
if (unlikely(!phba->sli4_hba.fp_eq))
|
||||
if (unlikely(!phba->sli4_hba.hba_eq))
|
||||
return IRQ_NONE;
|
||||
|
||||
/* Get to the EQ struct associated with this vector */
|
||||
fpeq = phba->sli4_hba.fp_eq[fcp_eqidx];
|
||||
fpeq = phba->sli4_hba.hba_eq[fcp_eqidx];
|
||||
if (unlikely(!fpeq))
|
||||
return IRQ_NONE;
|
||||
|
||||
|
@ -11953,7 +11866,7 @@ lpfc_sli4_fp_intr_handler(int irq, void *dev_id)
|
|||
* Process all the event on FCP fast-path EQ
|
||||
*/
|
||||
while ((eqe = lpfc_sli4_eq_get(fpeq))) {
|
||||
lpfc_sli4_fp_handle_eqe(phba, eqe, fcp_eqidx);
|
||||
lpfc_sli4_hba_handle_eqe(phba, eqe, fcp_eqidx);
|
||||
if (!(++ecount % fpeq->entry_repost))
|
||||
lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_NOARM);
|
||||
fpeq->EQ_processed++;
|
||||
|
@ -12001,8 +11914,8 @@ irqreturn_t
|
|||
lpfc_sli4_intr_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct lpfc_hba *phba;
|
||||
irqreturn_t sp_irq_rc, fp_irq_rc;
|
||||
bool fp_handled = false;
|
||||
irqreturn_t hba_irq_rc;
|
||||
bool hba_handled = false;
|
||||
uint32_t fcp_eqidx;
|
||||
|
||||
/* Get the driver's phba structure from the dev_id */
|
||||
|
@ -12011,22 +11924,17 @@ lpfc_sli4_intr_handler(int irq, void *dev_id)
|
|||
if (unlikely(!phba))
|
||||
return IRQ_NONE;
|
||||
|
||||
/*
|
||||
* Invokes slow-path host attention interrupt handling as appropriate.
|
||||
*/
|
||||
sp_irq_rc = lpfc_sli4_sp_intr_handler(irq, dev_id);
|
||||
|
||||
/*
|
||||
* Invoke fast-path host attention interrupt handling as appropriate.
|
||||
*/
|
||||
for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++) {
|
||||
fp_irq_rc = lpfc_sli4_fp_intr_handler(irq,
|
||||
for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_io_channel; fcp_eqidx++) {
|
||||
hba_irq_rc = lpfc_sli4_hba_intr_handler(irq,
|
||||
&phba->sli4_hba.fcp_eq_hdl[fcp_eqidx]);
|
||||
if (fp_irq_rc == IRQ_HANDLED)
|
||||
fp_handled |= true;
|
||||
if (hba_irq_rc == IRQ_HANDLED)
|
||||
hba_handled |= true;
|
||||
}
|
||||
|
||||
return (fp_handled == true) ? IRQ_HANDLED : sp_irq_rc;
|
||||
return (hba_handled == true) ? IRQ_HANDLED : IRQ_NONE;
|
||||
} /* lpfc_sli4_intr_handler */
|
||||
|
||||
/**
|
||||
|
@ -12157,7 +12065,7 @@ lpfc_modify_fcp_eq_delay(struct lpfc_hba *phba, uint16_t startq)
|
|||
union lpfc_sli4_cfg_shdr *shdr;
|
||||
uint16_t dmult;
|
||||
|
||||
if (startq >= phba->cfg_fcp_eq_count)
|
||||
if (startq >= phba->cfg_fcp_io_channel)
|
||||
return 0;
|
||||
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
|
@ -12174,9 +12082,9 @@ lpfc_modify_fcp_eq_delay(struct lpfc_hba *phba, uint16_t startq)
|
|||
dmult = LPFC_DMULT_CONST/phba->cfg_fcp_imax - 1;
|
||||
|
||||
cnt = 0;
|
||||
for (fcp_eqidx = startq; fcp_eqidx < phba->cfg_fcp_eq_count;
|
||||
for (fcp_eqidx = startq; fcp_eqidx < phba->cfg_fcp_io_channel;
|
||||
fcp_eqidx++) {
|
||||
eq = phba->sli4_hba.fp_eq[fcp_eqidx];
|
||||
eq = phba->sli4_hba.hba_eq[fcp_eqidx];
|
||||
if (!eq)
|
||||
continue;
|
||||
eq_delay->u.request.eq[cnt].eq_id = eq->queue_id;
|
||||
|
|
|
@ -34,18 +34,10 @@
|
|||
/* Number of SGL entries can be posted in a 4KB nonembedded mbox command */
|
||||
#define LPFC_NEMBED_MBOX_SGL_CNT 254
|
||||
|
||||
/* Multi-queue arrangement for fast-path FCP work queues */
|
||||
#define LPFC_FN_EQN_MAX 8
|
||||
#define LPFC_SP_EQN_DEF 1
|
||||
#define LPFC_FP_EQN_DEF 4
|
||||
#define LPFC_FP_EQN_MIN 1
|
||||
#define LPFC_FP_EQN_MAX (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF)
|
||||
|
||||
#define LPFC_FN_WQN_MAX 32
|
||||
#define LPFC_SP_WQN_DEF 1
|
||||
#define LPFC_FP_WQN_DEF 4
|
||||
#define LPFC_FP_WQN_MIN 1
|
||||
#define LPFC_FP_WQN_MAX (LPFC_FN_WQN_MAX - LPFC_SP_WQN_DEF)
|
||||
/* Multi-queue arrangement for FCP EQ/CQ/WQ tuples */
|
||||
#define LPFC_FCP_IO_CHAN_DEF 4
|
||||
#define LPFC_FCP_IO_CHAN_MIN 1
|
||||
#define LPFC_FCP_IO_CHAN_MAX 8
|
||||
|
||||
/*
|
||||
* Provide the default FCF Record attributes used by the driver
|
||||
|
@ -497,17 +489,19 @@ struct lpfc_sli4_hba {
|
|||
uint32_t cfg_eqn;
|
||||
uint32_t msix_vec_nr;
|
||||
struct lpfc_fcp_eq_hdl *fcp_eq_hdl; /* FCP per-WQ handle */
|
||||
|
||||
/* Pointers to the constructed SLI4 queues */
|
||||
struct lpfc_queue **fp_eq; /* Fast-path event queue */
|
||||
struct lpfc_queue *sp_eq; /* Slow-path event queue */
|
||||
struct lpfc_queue **hba_eq;/* Event queues for HBA */
|
||||
struct lpfc_queue **fcp_cq;/* Fast-path FCP compl queue */
|
||||
struct lpfc_queue **fcp_wq;/* Fast-path FCP work queue */
|
||||
uint16_t *fcp_cq_map;
|
||||
|
||||
struct lpfc_queue *mbx_cq; /* Slow-path mailbox complete queue */
|
||||
struct lpfc_queue *els_cq; /* Slow-path ELS response complete queue */
|
||||
struct lpfc_queue *mbx_wq; /* Slow-path MBOX work queue */
|
||||
struct lpfc_queue *els_wq; /* Slow-path ELS work queue */
|
||||
struct lpfc_queue *hdr_rq; /* Slow-path Header Receive queue */
|
||||
struct lpfc_queue *dat_rq; /* Slow-path Data Receive queue */
|
||||
struct lpfc_queue **fcp_cq;/* Fast-path FCP compl queue */
|
||||
struct lpfc_queue *mbx_cq; /* Slow-path mailbox complete queue */
|
||||
struct lpfc_queue *els_cq; /* Slow-path ELS response complete queue */
|
||||
|
||||
/* Setup information for various queue parameters */
|
||||
int eq_esize;
|
||||
|
|
Loading…
Reference in New Issue