scsi: qla2xxx: Select qpair depending on which CPU post_cmd() gets called
authorShreyas Deodhar <sdeodhar@marvell.com>
Thu, 22 Dec 2022 04:39:32 +0000 (20:39 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 12 Jan 2023 04:48:26 +0000 (23:48 -0500)
In current I/O path, Tx and Rx may not be processed on same CPU. This may
lead to thrashing and optimum performance may not be achieved.

Pick qpair such that Tx and Rx are processed on same CPU.

Signed-off-by: Shreyas Deodhar <sdeodhar@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_nvme.c
drivers/scsi/qla2xxx/qla_os.c

index 972f1144b9d323befaee1ca3d536280bbce3fa9b..ec0e987b71fa5d3ad2631cef062add518b26efcc 100644 (file)
@@ -3469,6 +3469,7 @@ struct qla_msix_entry {
        int have_irq;
        int in_use;
        uint32_t vector;
+       uint32_t vector_base0;
        uint16_t entry;
        char name[30];
        void *handle;
@@ -4125,6 +4126,7 @@ struct qla_hw_data {
        struct req_que **req_q_map;
        struct rsp_que **rsp_q_map;
        struct qla_qpair **queue_pair_map;
+       struct qla_qpair **qp_cpu_map;
        unsigned long req_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
        unsigned long rsp_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
        unsigned long qpair_qid_map[(QLA_MAX_QUEUES / 8)
index ce9e28b4d3394b729c0e3e4a34e140d9ed332185..c5e73d5a26b1622060a9a1ceaa0568a2fb040c38 100644 (file)
@@ -9426,8 +9426,6 @@ 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, raw_smp_processor_id());
 
                if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
                        if (ha->fw_attributes & BIT_4)
index b0ee307b5d4b9a3628bade5998fbffb414a554bb..cce6e425c1214a9aabaf9fe2677ba1ef0419cdb9 100644 (file)
@@ -515,3 +515,58 @@ fcport_is_bigger(fc_port_t *fcport)
 {
        return !fcport_is_smaller(fcport);
 }
+
+static inline struct qla_qpair *
+qla_mapq_nvme_select_qpair(struct qla_hw_data *ha, struct qla_qpair *qpair)
+{
+       int cpuid = smp_processor_id();
+
+       if (qpair->cpuid != cpuid &&
+           ha->qp_cpu_map[cpuid]) {
+               qpair = ha->qp_cpu_map[cpuid];
+       }
+       return qpair;
+}
+
+static inline void
+qla_mapq_init_qp_cpu_map(struct qla_hw_data *ha,
+                        struct qla_msix_entry *msix,
+                        struct qla_qpair *qpair)
+{
+       const struct cpumask *mask;
+       unsigned int cpu;
+
+       if (!ha->qp_cpu_map)
+               return;
+       mask = pci_irq_get_affinity(ha->pdev, msix->vector_base0);
+       qpair->cpuid = cpumask_first(mask);
+       for_each_cpu(cpu, mask) {
+               ha->qp_cpu_map[cpu] = qpair;
+       }
+       msix->cpuid = qpair->cpuid;
+}
+
+static inline void
+qla_mapq_free_qp_cpu_map(struct qla_hw_data *ha)
+{
+       if (ha->qp_cpu_map) {
+               kfree(ha->qp_cpu_map);
+               ha->qp_cpu_map = NULL;
+       }
+}
+
+static inline int qla_mapq_alloc_qp_cpu_map(struct qla_hw_data *ha)
+{
+       scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
+
+       if (!ha->qp_cpu_map) {
+               ha->qp_cpu_map = kcalloc(NR_CPUS, sizeof(struct qla_qpair *),
+                                        GFP_KERNEL);
+               if (!ha->qp_cpu_map) {
+                       ql_log(ql_log_fatal, vha, 0x0180,
+                              "Unable to allocate memory for qp_cpu_map ptrs.\n");
+                       return -1;
+               }
+       }
+       return 0;
+}
index cbbd7014da939b5236376ca918908807a5678561..46e8b38603f0495f1919d51cff583eeef1772e0a 100644 (file)
@@ -3769,7 +3769,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
 
        if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) {
                rsp->qpair->rcv_intr = 1;
-               qla_cpu_update(rsp->qpair, smp_processor_id());
        }
 
 #define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in)                 \
@@ -4377,6 +4376,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
        for (i = 0; i < ha->msix_count; i++) {
                qentry = &ha->msix_entries[i];
                qentry->vector = pci_irq_vector(ha->pdev, i);
+               qentry->vector_base0 = i;
                qentry->entry = i;
                qentry->have_irq = 0;
                qentry->in_use = 0;
@@ -4604,5 +4604,6 @@ int qla25xx_request_irq(struct qla_hw_data *ha, struct qla_qpair *qpair,
        }
        msix->have_irq = 1;
        msix->handle = qpair;
+       qla_mapq_init_qp_cpu_map(ha, msix, qpair);
        return ret;
 }
index c57e02a3552194c4f985dfd3e304e12714b39d37..648e8f7986065f88fe5fd421490b2da4e3bca2ee 100644 (file)
@@ -609,6 +609,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
        fc_port_t *fcport;
        struct srb_iocb *nvme;
        struct scsi_qla_host *vha;
+       struct qla_hw_data *ha;
        int rval;
        srb_t *sp;
        struct qla_qpair *qpair = hw_queue_handle;
@@ -629,6 +630,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
                return -ENODEV;
 
        vha = fcport->vha;
+       ha = vha->hw;
 
        if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
                return -EBUSY;
@@ -643,6 +645,8 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
        if (fcport->nvme_flag & NVME_FLAG_RESETTING)
                return -EBUSY;
 
+       qpair = qla_mapq_nvme_select_qpair(ha, qpair);
+
        /* Alloc SRB structure */
        sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC);
        if (!sp)
index d07a914559d34a57d9c0e99fb4d561286662523a..545167627e48e9fd171adaf54cbbd716fc0e68e3 100644 (file)
@@ -472,6 +472,11 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
                            "Unable to allocate memory for queue pair ptrs.\n");
                        goto fail_qpair_map;
                }
+               if (qla_mapq_alloc_qp_cpu_map(ha) != 0) {
+                       kfree(ha->queue_pair_map);
+                       ha->queue_pair_map = NULL;
+                       goto fail_qpair_map;
+               }
        }
 
        /*
@@ -546,6 +551,7 @@ static void qla2x00_free_queues(struct qla_hw_data *ha)
                ha->base_qpair = NULL;
        }
 
+       qla_mapq_free_qp_cpu_map(ha);
        spin_lock_irqsave(&ha->hardware_lock, flags);
        for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
                if (!test_bit(cnt, ha->req_qid_map))