Commit 83148866 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Martin K. Petersen

scsi: be2iscsi: switch to pci_alloc_irq_vectors

And get automatic MSI-X affinity for free.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarJitendra Bhivare <jitendra.bhivare@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent dbd34a61
...@@ -796,12 +796,12 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba) ...@@ -796,12 +796,12 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
struct pci_dev *pcidev = phba->pcidev; struct pci_dev *pcidev = phba->pcidev;
struct hwi_controller *phwi_ctrlr; struct hwi_controller *phwi_ctrlr;
struct hwi_context_memory *phwi_context; struct hwi_context_memory *phwi_context;
int ret, msix_vec, i, j; int ret, i, j;
phwi_ctrlr = phba->phwi_ctrlr; phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt; phwi_context = phwi_ctrlr->phwi_ctxt;
if (phba->msix_enabled) { if (pcidev->msix_enabled) {
for (i = 0; i < phba->num_cpus; i++) { for (i = 0; i < phba->num_cpus; i++) {
phba->msi_name[i] = kzalloc(BEISCSI_MSI_NAME, phba->msi_name[i] = kzalloc(BEISCSI_MSI_NAME,
GFP_KERNEL); GFP_KERNEL);
...@@ -812,9 +812,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba) ...@@ -812,9 +812,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
sprintf(phba->msi_name[i], "beiscsi_%02x_%02x", sprintf(phba->msi_name[i], "beiscsi_%02x_%02x",
phba->shost->host_no, i); phba->shost->host_no, i);
msix_vec = phba->msix_entries[i].vector; ret = request_irq(pci_irq_vector(pcidev, i),
ret = request_irq(msix_vec, be_isr_msix, 0, be_isr_msix, 0, phba->msi_name[i],
phba->msi_name[i],
&phwi_context->be_eq[i]); &phwi_context->be_eq[i]);
if (ret) { if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
...@@ -832,9 +831,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba) ...@@ -832,9 +831,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
} }
sprintf(phba->msi_name[i], "beiscsi_mcc_%02x", sprintf(phba->msi_name[i], "beiscsi_mcc_%02x",
phba->shost->host_no); phba->shost->host_no);
msix_vec = phba->msix_entries[i].vector; ret = request_irq(pci_irq_vector(pcidev, i), be_isr_mcc, 0,
ret = request_irq(msix_vec, be_isr_mcc, 0, phba->msi_name[i], phba->msi_name[i], &phwi_context->be_eq[i]);
&phwi_context->be_eq[i]);
if (ret) { if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT , beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT ,
"BM_%d : beiscsi_init_irqs-" "BM_%d : beiscsi_init_irqs-"
...@@ -856,9 +854,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba) ...@@ -856,9 +854,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
return 0; return 0;
free_msix_irqs: free_msix_irqs:
for (j = i - 1; j >= 0; j--) { for (j = i - 1; j >= 0; j--) {
free_irq(pci_irq_vector(pcidev, i), &phwi_context->be_eq[j]);
kfree(phba->msi_name[j]); kfree(phba->msi_name[j]);
msix_vec = phba->msix_entries[j].vector;
free_irq(msix_vec, &phwi_context->be_eq[j]);
} }
return ret; return ret;
} }
...@@ -3000,7 +2997,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba, ...@@ -3000,7 +2997,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba,
num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \ num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
sizeof(struct be_eq_entry)); sizeof(struct be_eq_entry));
if (phba->msix_enabled) if (phba->pcidev->msix_enabled)
eq_for_mcc = 1; eq_for_mcc = 1;
else else
eq_for_mcc = 0; eq_for_mcc = 0;
...@@ -3510,7 +3507,7 @@ static int be_mcc_queues_create(struct beiscsi_hba *phba, ...@@ -3510,7 +3507,7 @@ static int be_mcc_queues_create(struct beiscsi_hba *phba,
sizeof(struct be_mcc_compl))) sizeof(struct be_mcc_compl)))
goto err; goto err;
/* Ask BE to create MCC compl queue; */ /* Ask BE to create MCC compl queue; */
if (phba->msix_enabled) { if (phba->pcidev->msix_enabled) {
if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq
[phba->num_cpus].q, false, true, 0)) [phba->num_cpus].q, false, true, 0))
goto mcc_cq_free; goto mcc_cq_free;
...@@ -3541,42 +3538,35 @@ static int be_mcc_queues_create(struct beiscsi_hba *phba, ...@@ -3541,42 +3538,35 @@ static int be_mcc_queues_create(struct beiscsi_hba *phba,
return -ENOMEM; return -ENOMEM;
} }
/** static void be2iscsi_enable_msix(struct beiscsi_hba *phba)
* find_num_cpus()- Get the CPU online count
* @phba: ptr to priv structure
*
* CPU count is used for creating EQ.
**/
static void find_num_cpus(struct beiscsi_hba *phba)
{ {
int num_cpus = 0; int nvec = 1;
num_cpus = num_online_cpus();
switch (phba->generation) { switch (phba->generation) {
case BE_GEN2: case BE_GEN2:
case BE_GEN3: case BE_GEN3:
phba->num_cpus = (num_cpus > BEISCSI_MAX_NUM_CPUS) ? nvec = BEISCSI_MAX_NUM_CPUS + 1;
BEISCSI_MAX_NUM_CPUS : num_cpus;
break; break;
case BE_GEN4: case BE_GEN4:
/* nvec = phba->fw_config.eqid_count;
* If eqid_count == 1 fall back to
* INTX mechanism
**/
if (phba->fw_config.eqid_count == 1) {
enable_msix = 0;
phba->num_cpus = 1;
return;
}
phba->num_cpus =
(num_cpus > (phba->fw_config.eqid_count - 1)) ?
(phba->fw_config.eqid_count - 1) : num_cpus;
break; break;
default: default:
phba->num_cpus = 1; nvec = 2;
break;
}
/* if eqid_count == 1 fall back to INTX */
if (enable_msix && nvec > 1) {
const struct irq_affinity desc = { .post_vectors = 1 };
if (pci_alloc_irq_vectors_affinity(phba->pcidev, 2, nvec,
PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, &desc) < 0) {
phba->num_cpus = nvec - 1;
return;
}
} }
phba->num_cpus = 1;
} }
static void hwi_purge_eq(struct beiscsi_hba *phba) static void hwi_purge_eq(struct beiscsi_hba *phba)
...@@ -3593,7 +3583,7 @@ static void hwi_purge_eq(struct beiscsi_hba *phba) ...@@ -3593,7 +3583,7 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
phwi_ctrlr = phba->phwi_ctrlr; phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt; phwi_context = phwi_ctrlr->phwi_ctxt;
if (phba->msix_enabled) if (phba->pcidev->msix_enabled)
eq_msix = 1; eq_msix = 1;
else else
eq_msix = 0; eq_msix = 0;
...@@ -3671,7 +3661,7 @@ static void hwi_cleanup_port(struct beiscsi_hba *phba) ...@@ -3671,7 +3661,7 @@ static void hwi_cleanup_port(struct beiscsi_hba *phba)
} }
be_mcc_queues_destroy(phba); be_mcc_queues_destroy(phba);
if (phba->msix_enabled) if (phba->pcidev->msix_enabled)
eq_for_mcc = 1; eq_for_mcc = 1;
else else
eq_for_mcc = 0; eq_for_mcc = 0;
...@@ -4117,7 +4107,7 @@ static void hwi_enable_intr(struct beiscsi_hba *phba) ...@@ -4117,7 +4107,7 @@ static void hwi_enable_intr(struct beiscsi_hba *phba)
iowrite32(reg, addr); iowrite32(reg, addr);
} }
if (!phba->msix_enabled) { if (!phba->pcidev->msix_enabled) {
eq = &phwi_context->be_eq[0].q; eq = &phwi_context->be_eq[0].q;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
"BM_%d : eq->id=%d\n", eq->id); "BM_%d : eq->id=%d\n", eq->id);
...@@ -5240,19 +5230,6 @@ static void beiscsi_eqd_update_work(struct work_struct *work) ...@@ -5240,19 +5230,6 @@ static void beiscsi_eqd_update_work(struct work_struct *work)
msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL)); msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
} }
static void beiscsi_msix_enable(struct beiscsi_hba *phba)
{
int i, status;
for (i = 0; i <= phba->num_cpus; i++)
phba->msix_entries[i].entry = i;
status = pci_enable_msix_range(phba->pcidev, phba->msix_entries,
phba->num_cpus + 1, phba->num_cpus + 1);
if (status > 0)
phba->msix_enabled = true;
}
static void beiscsi_hw_tpe_check(unsigned long ptr) static void beiscsi_hw_tpe_check(unsigned long ptr)
{ {
struct beiscsi_hba *phba; struct beiscsi_hba *phba;
...@@ -5320,15 +5297,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba) ...@@ -5320,15 +5297,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba)
if (ret) if (ret)
return ret; return ret;
if (enable_msix) be2iscsi_enable_msix(phba);
find_num_cpus(phba);
else
phba->num_cpus = 1;
if (enable_msix) {
beiscsi_msix_enable(phba);
if (!phba->msix_enabled)
phba->num_cpus = 1;
}
beiscsi_get_params(phba); beiscsi_get_params(phba);
/* Re-enable UER. If different TPE occurs then it is recoverable. */ /* Re-enable UER. If different TPE occurs then it is recoverable. */
...@@ -5357,7 +5326,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba) ...@@ -5357,7 +5326,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba)
irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget, be_iopoll); irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget, be_iopoll);
} }
i = (phba->msix_enabled) ? i : 0; i = (phba->pcidev->msix_enabled) ? i : 0;
/* Work item for MCC handling */ /* Work item for MCC handling */
pbe_eq = &phwi_context->be_eq[i]; pbe_eq = &phwi_context->be_eq[i];
INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work); INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work);
...@@ -5395,9 +5364,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba) ...@@ -5395,9 +5364,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba)
hwi_cleanup_port(phba); hwi_cleanup_port(phba);
disable_msix: disable_msix:
if (phba->msix_enabled) pci_free_irq_vectors(phba->pcidev);
pci_disable_msix(phba->pcidev);
return ret; return ret;
} }
...@@ -5414,7 +5381,7 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload) ...@@ -5414,7 +5381,7 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload)
struct hwi_context_memory *phwi_context; struct hwi_context_memory *phwi_context;
struct hwi_controller *phwi_ctrlr; struct hwi_controller *phwi_ctrlr;
struct be_eq_obj *pbe_eq; struct be_eq_obj *pbe_eq;
unsigned int i, msix_vec; unsigned int i;
if (!test_and_clear_bit(BEISCSI_HBA_ONLINE, &phba->state)) if (!test_and_clear_bit(BEISCSI_HBA_ONLINE, &phba->state))
return; return;
...@@ -5422,16 +5389,16 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload) ...@@ -5422,16 +5389,16 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload)
phwi_ctrlr = phba->phwi_ctrlr; phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt; phwi_context = phwi_ctrlr->phwi_ctxt;
hwi_disable_intr(phba); hwi_disable_intr(phba);
if (phba->msix_enabled) { if (phba->pcidev->msix_enabled) {
for (i = 0; i <= phba->num_cpus; i++) { for (i = 0; i <= phba->num_cpus; i++) {
msix_vec = phba->msix_entries[i].vector; free_irq(pci_irq_vector(phba->pcidev, i),
free_irq(msix_vec, &phwi_context->be_eq[i]); &phwi_context->be_eq[i]);
kfree(phba->msi_name[i]); kfree(phba->msi_name[i]);
} }
} else } else
if (phba->pcidev->irq) if (phba->pcidev->irq)
free_irq(phba->pcidev->irq, phba); free_irq(phba->pcidev->irq, phba);
pci_disable_msix(phba->pcidev); pci_free_irq_vectors(phba->pcidev);
for (i = 0; i < phba->num_cpus; i++) { for (i = 0; i < phba->num_cpus; i++) {
pbe_eq = &phwi_context->be_eq[i]; pbe_eq = &phwi_context->be_eq[i];
...@@ -5641,21 +5608,12 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, ...@@ -5641,21 +5608,12 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
beiscsi_get_params(phba); beiscsi_get_params(phba);
beiscsi_set_uer_feature(phba); beiscsi_set_uer_feature(phba);
if (enable_msix) be2iscsi_enable_msix(phba);
find_num_cpus(phba);
else
phba->num_cpus = 1;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
"BM_%d : num_cpus = %d\n", "BM_%d : num_cpus = %d\n",
phba->num_cpus); phba->num_cpus);
if (enable_msix) {
beiscsi_msix_enable(phba);
if (!phba->msix_enabled)
phba->num_cpus = 1;
}
phba->shost->max_id = phba->params.cxns_per_ctrl; phba->shost->max_id = phba->params.cxns_per_ctrl;
phba->shost->can_queue = phba->params.ios_per_ctrl; phba->shost->can_queue = phba->params.ios_per_ctrl;
ret = beiscsi_get_memory(phba); ret = beiscsi_get_memory(phba);
...@@ -5705,7 +5663,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, ...@@ -5705,7 +5663,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget, be_iopoll); irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget, be_iopoll);
} }
i = (phba->msix_enabled) ? i : 0; i = (phba->pcidev->msix_enabled) ? i : 0;
/* Work item for MCC handling */ /* Work item for MCC handling */
pbe_eq = &phwi_context->be_eq[i]; pbe_eq = &phwi_context->be_eq[i];
INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work); INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work);
...@@ -5776,8 +5734,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, ...@@ -5776,8 +5734,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
phba->ctrl.mbox_mem_alloced.dma); phba->ctrl.mbox_mem_alloced.dma);
beiscsi_unmap_pci_function(phba); beiscsi_unmap_pci_function(phba);
hba_free: hba_free:
if (phba->msix_enabled) pci_disable_msix(phba->pcidev);
pci_disable_msix(phba->pcidev);
pci_dev_put(phba->pcidev); pci_dev_put(phba->pcidev);
iscsi_host_free(phba->shost); iscsi_host_free(phba->shost);
pci_set_drvdata(pcidev, NULL); pci_set_drvdata(pcidev, NULL);
......
...@@ -317,9 +317,7 @@ struct beiscsi_hba { ...@@ -317,9 +317,7 @@ struct beiscsi_hba {
struct pci_dev *pcidev; struct pci_dev *pcidev;
unsigned int num_cpus; unsigned int num_cpus;
unsigned int nxt_cqid; unsigned int nxt_cqid;
struct msix_entry msix_entries[MAX_CPUS];
char *msi_name[MAX_CPUS]; char *msi_name[MAX_CPUS];
bool msix_enabled;
struct be_mem_descriptor *init_mem; struct be_mem_descriptor *init_mem;
unsigned short io_sgl_alloc_index; unsigned short io_sgl_alloc_index;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment