Skip to content

Commit

Permalink
scsi: lpfc: Allow override of hardware queue selection policies
Browse files Browse the repository at this point in the history
Default behavior is to use the information from the upper IO stacks to
select the hardware queue to use for IO submission.  Which typically has
good cpu affinity.

However, the driver, when used on some variants of the upstream kernel, has
found queuing information to be suboptimal for FCP or IO completion locked
on particular cpus.

For command submission situations, the lpfc_fcp_io_sched module parameter
can be set to specify a hardware queue selection policy that overrides the
os stack information.

For IO completion situations, rather than queing cq processing based on the
cpu servicing the interrupting event, schedule the cq processing on the cpu
associated with the hardware queue's cq.

Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
James Smart authored and Martin K. Petersen committed Feb 6, 2019
1 parent c490850 commit 45aa312
Showing 5 changed files with 20 additions and 11 deletions.
11 changes: 6 additions & 5 deletions drivers/scsi/lpfc/lpfc_attr.c
Original file line number Diff line number Diff line change
@@ -5275,23 +5275,24 @@ LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");
/*
* lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
* range is [0,1]. Default value is 0.
* For [0], FCP commands are issued to Work Queues ina round robin fashion.
* For [0], FCP commands are issued to Work Queues based on upper layer
* hardware queue index.
* For [1], FCP commands are issued to a Work Queue associated with the
* current CPU.
*
* LPFC_FCP_SCHED_ROUND_ROBIN == 0
* LPFC_FCP_SCHED_BY_HDWQ == 0
* LPFC_FCP_SCHED_BY_CPU == 1
*
* The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu
* affinity for FCP/NVME I/Os through Work Queues associated with the current
* CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os
* through WQs will be used.
*/
LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_ROUND_ROBIN,
LPFC_FCP_SCHED_ROUND_ROBIN,
LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_BY_HDWQ,
LPFC_FCP_SCHED_BY_HDWQ,
LPFC_FCP_SCHED_BY_CPU,
"Determine scheduling algorithm for "
"issuing commands [0] - Round Robin, [1] - Current CPU");
"issuing commands [0] - Hardware Queue, [1] - Current CPU");

/*
* lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN
2 changes: 1 addition & 1 deletion drivers/scsi/lpfc/lpfc_hw4.h
Original file line number Diff line number Diff line change
@@ -194,7 +194,7 @@ struct lpfc_sli_intf {
#define LPFC_ACT_INTR_CNT 4

/* Algrithmns for scheduling FCP commands to WQs */
#define LPFC_FCP_SCHED_ROUND_ROBIN 0
#define LPFC_FCP_SCHED_BY_HDWQ 0
#define LPFC_FCP_SCHED_BY_CPU 1

/* Algrithmns for NameServer Query after RSCN */
14 changes: 11 additions & 3 deletions drivers/scsi/lpfc/lpfc_nvme.c
Original file line number Diff line number Diff line change
@@ -1546,8 +1546,17 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
}
}

lpfc_ncmd = lpfc_get_nvme_buf(phba, ndlp,
lpfc_queue_info->index, expedite);
if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) {
idx = lpfc_queue_info->index;
} else {
cpu = smp_processor_id();
if (cpu < phba->cfg_hdw_queue)
idx = cpu;
else
idx = cpu % phba->cfg_hdw_queue;
}

lpfc_ncmd = lpfc_get_nvme_buf(phba, ndlp, idx, expedite);
if (lpfc_ncmd == NULL) {
atomic_inc(&lport->xmt_fcp_noxri);
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR,
@@ -1585,7 +1594,6 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
* index to use and that they have affinitized a CPU to this hardware
* queue. A hardware queue maps to a driver MSI-X vector/EQ/CQ/WQ.
*/
idx = lpfc_queue_info->index;
lpfc_ncmd->cur_iocbq.hba_wqidx = idx;
cstat = &phba->sli4_hba.hdwq[idx].nvme_cstat;

2 changes: 1 addition & 1 deletion drivers/scsi/lpfc/lpfc_scsi.c
Original file line number Diff line number Diff line change
@@ -688,7 +688,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
int tag;

cpu = smp_processor_id();
if (cmnd) {
if (cmnd && phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) {
tag = blk_mq_unique_tag(cmnd->request);
idx = blk_mq_unique_tag_to_hwq(tag);
} else {
2 changes: 1 addition & 1 deletion drivers/scsi/lpfc/lpfc_sli.c
Original file line number Diff line number Diff line change
@@ -14106,7 +14106,7 @@ lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
/* Save EQ associated with this CQ */
cq->assoc_qp = phba->sli4_hba.hdwq[qidx].hba_eq;

if (!queue_work(phba->wq, &cq->irqwork))
if (!queue_work_on(cq->chann, phba->wq, &cq->irqwork))
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0363 Cannot schedule soft IRQ "
"for CQ eqcqid=%d, cqid=%d on CPU %d\n",

0 comments on commit 45aa312

Please sign in to comment.