scsi: be2iscsi: switch to pci_alloc_irq_vectors
authorChristoph Hellwig <hch@lst.de>
Fri, 13 Jan 2017 16:29:48 +0000 (17:29 +0100)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 30 Mar 2017 15:37:16 +0000 (11:37 -0400)
And get automatic MSI-X affinity for free.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h

index 61b7f5bf6bc62169aa488903fe35fd2ba7842600..f862332261f82230a9fec82531c47d3f667f9126 100644 (file)
@@ -796,12 +796,12 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
        struct pci_dev *pcidev = phba->pcidev;
        struct hwi_controller *phwi_ctrlr;
        struct hwi_context_memory *phwi_context;
-       int ret, msix_vec, i, j;
+       int ret, i, j;
 
        phwi_ctrlr = phba->phwi_ctrlr;
        phwi_context = phwi_ctrlr->phwi_ctxt;
 
-       if (phba->msix_enabled) {
+       if (pcidev->msix_enabled) {
                for (i = 0; i < phba->num_cpus; i++) {
                        phba->msi_name[i] = kzalloc(BEISCSI_MSI_NAME,
                                                    GFP_KERNEL);
@@ -812,9 +812,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 
                        sprintf(phba->msi_name[i], "beiscsi_%02x_%02x",
                                phba->shost->host_no, i);
-                       msix_vec = phba->msix_entries[i].vector;
-                       ret = request_irq(msix_vec, be_isr_msix, 0,
-                                         phba->msi_name[i],
+                       ret = request_irq(pci_irq_vector(pcidev, i),
+                                         be_isr_msix, 0, phba->msi_name[i],
                                          &phwi_context->be_eq[i]);
                        if (ret) {
                                beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -832,9 +831,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
                }
                sprintf(phba->msi_name[i], "beiscsi_mcc_%02x",
                        phba->shost->host_no);
-               msix_vec = phba->msix_entries[i].vector;
-               ret = request_irq(msix_vec, be_isr_mcc, 0, phba->msi_name[i],
-                                 &phwi_context->be_eq[i]);
+               ret = request_irq(pci_irq_vector(pcidev, i), be_isr_mcc, 0,
+                                 phba->msi_name[i], &phwi_context->be_eq[i]);
                if (ret) {
                        beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT ,
                                    "BM_%d : beiscsi_init_irqs-"
@@ -856,9 +854,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
        return 0;
 free_msix_irqs:
        for (j = i - 1; j >= 0; j--) {
+               free_irq(pci_irq_vector(pcidev, i), &phwi_context->be_eq[j]);
                kfree(phba->msi_name[j]);
-               msix_vec = phba->msix_entries[j].vector;
-               free_irq(msix_vec, &phwi_context->be_eq[j]);
        }
        return ret;
 }
@@ -3000,7 +2997,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba,
        num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
                                      sizeof(struct be_eq_entry));
 
-       if (phba->msix_enabled)
+       if (phba->pcidev->msix_enabled)
                eq_for_mcc = 1;
        else
                eq_for_mcc = 0;
@@ -3510,7 +3507,7 @@ static int be_mcc_queues_create(struct beiscsi_hba *phba,
                        sizeof(struct be_mcc_compl)))
                goto err;
        /* 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
                                         [phba->num_cpus].q, false, true, 0))
                goto mcc_cq_free;
@@ -3541,42 +3538,35 @@ err:
        return -ENOMEM;
 }
 
-/**
- * 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)
+static void be2iscsi_enable_msix(struct beiscsi_hba *phba)
 {
-       int  num_cpus = 0;
-
-       num_cpus = num_online_cpus();
+       int nvec = 1;
 
        switch (phba->generation) {
        case BE_GEN2:
        case BE_GEN3:
-               phba->num_cpus = (num_cpus > BEISCSI_MAX_NUM_CPUS) ?
-                                 BEISCSI_MAX_NUM_CPUS : num_cpus;
+               nvec = BEISCSI_MAX_NUM_CPUS + 1;
                break;
        case BE_GEN4:
-               /*
-                * 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;
+               nvec = phba->fw_config.eqid_count;
                break;
        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)
@@ -3593,7 +3583,7 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
 
        phwi_ctrlr = phba->phwi_ctrlr;
        phwi_context = phwi_ctrlr->phwi_ctxt;
-       if (phba->msix_enabled)
+       if (phba->pcidev->msix_enabled)
                eq_msix = 1;
        else
                eq_msix = 0;
@@ -3671,7 +3661,7 @@ static void hwi_cleanup_port(struct beiscsi_hba *phba)
        }
 
        be_mcc_queues_destroy(phba);
-       if (phba->msix_enabled)
+       if (phba->pcidev->msix_enabled)
                eq_for_mcc = 1;
        else
                eq_for_mcc = 0;
@@ -4117,7 +4107,7 @@ static void hwi_enable_intr(struct beiscsi_hba *phba)
                iowrite32(reg, addr);
        }
 
-       if (!phba->msix_enabled) {
+       if (!phba->pcidev->msix_enabled) {
                eq = &phwi_context->be_eq[0].q;
                beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
                            "BM_%d : eq->id=%d\n", eq->id);
@@ -5240,19 +5230,6 @@ static void beiscsi_eqd_update_work(struct work_struct *work)
                              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)
 {
        struct beiscsi_hba *phba;
@@ -5320,15 +5297,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba)
        if (ret)
                return ret;
 
-       if (enable_msix)
-               find_num_cpus(phba);
-       else
-               phba->num_cpus = 1;
-       if (enable_msix) {
-               beiscsi_msix_enable(phba);
-               if (!phba->msix_enabled)
-                       phba->num_cpus = 1;
-       }
+       be2iscsi_enable_msix(phba);
 
        beiscsi_get_params(phba);
        /* Re-enable UER. If different TPE occurs then it is recoverable. */
@@ -5357,7 +5326,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba)
                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 */
        pbe_eq = &phwi_context->be_eq[i];
        INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work);
@@ -5395,9 +5364,7 @@ cleanup_port:
        hwi_cleanup_port(phba);
 
 disable_msix:
-       if (phba->msix_enabled)
-               pci_disable_msix(phba->pcidev);
-
+       pci_free_irq_vectors(phba->pcidev);
        return ret;
 }
 
@@ -5414,7 +5381,7 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload)
        struct hwi_context_memory *phwi_context;
        struct hwi_controller *phwi_ctrlr;
        struct be_eq_obj *pbe_eq;
-       unsigned int i, msix_vec;
+       unsigned int i;
 
        if (!test_and_clear_bit(BEISCSI_HBA_ONLINE, &phba->state))
                return;
@@ -5422,16 +5389,16 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload)
        phwi_ctrlr = phba->phwi_ctrlr;
        phwi_context = phwi_ctrlr->phwi_ctxt;
        hwi_disable_intr(phba);
-       if (phba->msix_enabled) {
+       if (phba->pcidev->msix_enabled) {
                for (i = 0; i <= phba->num_cpus; i++) {
-                       msix_vec = phba->msix_entries[i].vector;
-                       free_irq(msix_vec, &phwi_context->be_eq[i]);
+                       free_irq(pci_irq_vector(phba->pcidev, i),
+                               &phwi_context->be_eq[i]);
                        kfree(phba->msi_name[i]);
                }
        } else
                if (phba->pcidev->irq)
                        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++) {
                pbe_eq = &phwi_context->be_eq[i];
@@ -5641,21 +5608,12 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
        beiscsi_get_params(phba);
        beiscsi_set_uer_feature(phba);
 
-       if (enable_msix)
-               find_num_cpus(phba);
-       else
-               phba->num_cpus = 1;
+       be2iscsi_enable_msix(phba);
 
        beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
                    "BM_%d : num_cpus = %d\n",
                    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->can_queue = phba->params.ios_per_ctrl;
        ret = beiscsi_get_memory(phba);
@@ -5705,7 +5663,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
                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 */
        pbe_eq = &phwi_context->be_eq[i];
        INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work);
@@ -5776,8 +5734,7 @@ free_port:
                           phba->ctrl.mbox_mem_alloced.dma);
        beiscsi_unmap_pci_function(phba);
 hba_free:
-       if (phba->msix_enabled)
-               pci_disable_msix(phba->pcidev);
+       pci_disable_msix(phba->pcidev);
        pci_dev_put(phba->pcidev);
        iscsi_host_free(phba->shost);
        pci_set_drvdata(pcidev, NULL);
index ee18a954a1a84dc15d8948d55b0dc9c42b447eb1..338dbe0800c16e6d0298636d1d5d45b7e9b56c18 100644 (file)
@@ -317,9 +317,7 @@ struct beiscsi_hba {
        struct pci_dev *pcidev;
        unsigned int num_cpus;
        unsigned int nxt_cqid;
-       struct msix_entry msix_entries[MAX_CPUS];
        char *msi_name[MAX_CPUS];
-       bool msix_enabled;
        struct be_mem_descriptor *init_mem;
 
        unsigned short io_sgl_alloc_index;