summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2019-01-28 14:14:29 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2019-02-05 22:29:09 -0500
commit45aa312e211f1c8c44a8e90c184a21bbb5b5572c (patch)
treeb205f600bf511b4ba1851bf7386085b9be0006ab
parentc490850a094794e7515737a6939146966c826577 (diff)
scsi: lpfc: Allow override of hardware queue selection policies
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>
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c11
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_nvme.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c2
5 files changed, 20 insertions, 11 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 47aa2af885a4..93a96491899c 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5275,11 +5275,12 @@ LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");
5275/* 5275/*
5276 * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds 5276 * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
5277 * range is [0,1]. Default value is 0. 5277 * range is [0,1]. Default value is 0.
5278 * For [0], FCP commands are issued to Work Queues ina round robin fashion. 5278 * For [0], FCP commands are issued to Work Queues based on upper layer
5279 * hardware queue index.
5279 * For [1], FCP commands are issued to a Work Queue associated with the 5280 * For [1], FCP commands are issued to a Work Queue associated with the
5280 * current CPU. 5281 * current CPU.
5281 * 5282 *
5282 * LPFC_FCP_SCHED_ROUND_ROBIN == 0 5283 * LPFC_FCP_SCHED_BY_HDWQ == 0
5283 * LPFC_FCP_SCHED_BY_CPU == 1 5284 * LPFC_FCP_SCHED_BY_CPU == 1
5284 * 5285 *
5285 * The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu 5286 * The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu
@@ -5287,11 +5288,11 @@ LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");
5287 * CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os 5288 * CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os
5288 * through WQs will be used. 5289 * through WQs will be used.
5289 */ 5290 */
5290LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_ROUND_ROBIN, 5291LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_BY_HDWQ,
5291 LPFC_FCP_SCHED_ROUND_ROBIN, 5292 LPFC_FCP_SCHED_BY_HDWQ,
5292 LPFC_FCP_SCHED_BY_CPU, 5293 LPFC_FCP_SCHED_BY_CPU,
5293 "Determine scheduling algorithm for " 5294 "Determine scheduling algorithm for "
5294 "issuing commands [0] - Round Robin, [1] - Current CPU"); 5295 "issuing commands [0] - Hardware Queue, [1] - Current CPU");
5295 5296
5296/* 5297/*
5297 * lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN 5298 * lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index c15b9b6fb840..cd39845c909f 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -194,7 +194,7 @@ struct lpfc_sli_intf {
194#define LPFC_ACT_INTR_CNT 4 194#define LPFC_ACT_INTR_CNT 4
195 195
196/* Algrithmns for scheduling FCP commands to WQs */ 196/* Algrithmns for scheduling FCP commands to WQs */
197#define LPFC_FCP_SCHED_ROUND_ROBIN 0 197#define LPFC_FCP_SCHED_BY_HDWQ 0
198#define LPFC_FCP_SCHED_BY_CPU 1 198#define LPFC_FCP_SCHED_BY_CPU 1
199 199
200/* Algrithmns for NameServer Query after RSCN */ 200/* Algrithmns for NameServer Query after RSCN */
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 0c6c91d39e2f..c9aacd56a449 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1546,8 +1546,17 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
1546 } 1546 }
1547 } 1547 }
1548 1548
1549 lpfc_ncmd = lpfc_get_nvme_buf(phba, ndlp, 1549 if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) {
1550 lpfc_queue_info->index, expedite); 1550 idx = lpfc_queue_info->index;
1551 } else {
1552 cpu = smp_processor_id();
1553 if (cpu < phba->cfg_hdw_queue)
1554 idx = cpu;
1555 else
1556 idx = cpu % phba->cfg_hdw_queue;
1557 }
1558
1559 lpfc_ncmd = lpfc_get_nvme_buf(phba, ndlp, idx, expedite);
1551 if (lpfc_ncmd == NULL) { 1560 if (lpfc_ncmd == NULL) {
1552 atomic_inc(&lport->xmt_fcp_noxri); 1561 atomic_inc(&lport->xmt_fcp_noxri);
1553 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, 1562 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,
1585 * index to use and that they have affinitized a CPU to this hardware 1594 * index to use and that they have affinitized a CPU to this hardware
1586 * queue. A hardware queue maps to a driver MSI-X vector/EQ/CQ/WQ. 1595 * queue. A hardware queue maps to a driver MSI-X vector/EQ/CQ/WQ.
1587 */ 1596 */
1588 idx = lpfc_queue_info->index;
1589 lpfc_ncmd->cur_iocbq.hba_wqidx = idx; 1597 lpfc_ncmd->cur_iocbq.hba_wqidx = idx;
1590 cstat = &phba->sli4_hba.hdwq[idx].nvme_cstat; 1598 cstat = &phba->sli4_hba.hdwq[idx].nvme_cstat;
1591 1599
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c824ed3be4f9..7b22cc995d7f 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -688,7 +688,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
688 int tag; 688 int tag;
689 689
690 cpu = smp_processor_id(); 690 cpu = smp_processor_id();
691 if (cmnd) { 691 if (cmnd && phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) {
692 tag = blk_mq_unique_tag(cmnd->request); 692 tag = blk_mq_unique_tag(cmnd->request);
693 idx = blk_mq_unique_tag_to_hwq(tag); 693 idx = blk_mq_unique_tag_to_hwq(tag);
694 } else { 694 } else {
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 4443d0d43053..c0f0adccdea7 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -14106,7 +14106,7 @@ process_cq:
14106 /* Save EQ associated with this CQ */ 14106 /* Save EQ associated with this CQ */
14107 cq->assoc_qp = phba->sli4_hba.hdwq[qidx].hba_eq; 14107 cq->assoc_qp = phba->sli4_hba.hdwq[qidx].hba_eq;
14108 14108
14109 if (!queue_work(phba->wq, &cq->irqwork)) 14109 if (!queue_work_on(cq->chann, phba->wq, &cq->irqwork))
14110 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 14110 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
14111 "0363 Cannot schedule soft IRQ " 14111 "0363 Cannot schedule soft IRQ "
14112 "for CQ eqcqid=%d, cqid=%d on CPU %d\n", 14112 "for CQ eqcqid=%d, cqid=%d on CPU %d\n",