Skip to content

Commit

Permalink
scsi: qla2xxx: Select qpair depending on which CPU post_cmd() gets ca…
Browse files Browse the repository at this point in the history
…lled

[ Upstream commit 1d201c8 ]

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>
Stable-dep-of: 59f10a0 ("scsi: qla2xxx: Use raw_smp_processor_id() instead of smp_processor_id()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Shreyas Deodhar authored and gregkh committed Oct 6, 2023
1 parent 3a8ac77 commit 35c02a3
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 3 deletions.
2 changes: 2 additions & 0 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -3475,6 +3475,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;
Expand Down Expand Up @@ -4133,6 +4134,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)
Expand Down
2 changes: 0 additions & 2 deletions drivers/scsi/qla2xxx/qla_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -9758,8 +9758,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)
Expand Down
55 changes: 55 additions & 0 deletions drivers/scsi/qla2xxx/qla_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -573,3 +573,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;
}
3 changes: 2 additions & 1 deletion drivers/scsi/qla2xxx/qla_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -3819,7 +3819,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) \
Expand Down Expand Up @@ -4425,6 +4424,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;
Expand Down Expand Up @@ -4652,5 +4652,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;
}
4 changes: 4 additions & 0 deletions drivers/scsi/qla2xxx/qla_nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions drivers/scsi/qla2xxx/qla_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,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;
}
}

/*
Expand Down Expand Up @@ -554,6 +559,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))
Expand Down

0 comments on commit 35c02a3

Please sign in to comment.