int have_irq;
        int in_use;
        uint32_t vector;
+       uint32_t vector_base0;
        uint16_t entry;
        char name[30];
        void *handle;
        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)
 
                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)
 
 {
        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;
+}
 
 
        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)                 \
        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;
        }
        msix->have_irq = 1;
        msix->handle = qpair;
+       qla_mapq_init_qp_cpu_map(ha, msix, qpair);
        return ret;
 }
 
        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;
                return -ENODEV;
 
        vha = fcport->vha;
+       ha = vha->hw;
 
        if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
                return -EBUSY;
        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)
 
                            "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;
+               }
        }
 
        /*
                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))