]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
net: aquantia: Limit number of vectors to actually allocated irqs
authorIgor Russkikh <igor.russkikh@aquantia.com>
Mon, 7 May 2018 13:10:39 +0000 (16:10 +0300)
committerDavid S. Miller <davem@davemloft.net>
Tue, 8 May 2018 04:06:44 +0000 (00:06 -0400)
Driver should use pci_alloc_irq_vectors return value to correct number
of allocated vectors and napi instances. Otherwise it'll panic later
in pci_irq_vector.

Driver also should allow more than one MSI vectors to be allocated.

Error return path from pci_alloc_irq_vectors is also fixed to revert
resources in a correct sequence when error happens.

Reported-by: Long, Nicholas <nicholas.a.long@baesystems.com>
Fixes: 23ee07a ("net: aquantia: Cleanup pci functions module")
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.h
drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c

index 720760d467fa0443e60525700183809ecb499889..1a1a6380c128c4522b330907cc16258f0e012189 100644 (file)
@@ -95,6 +95,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
        /*rss rings */
        cfg->vecs = min(cfg->aq_hw_caps->vecs, AQ_CFG_VECS_DEF);
        cfg->vecs = min(cfg->vecs, num_online_cpus());
+       cfg->vecs = min(cfg->vecs, self->irqvecs);
        /* cfg->vecs should be power of 2 for RSS */
        if (cfg->vecs >= 8U)
                cfg->vecs = 8U;
index 219b550d16650bd6b205fb6e10855627a0fd277b..faa533a0ec474116b7d84369c947a7f0f1bfa853 100644 (file)
@@ -80,6 +80,7 @@ struct aq_nic_s {
 
        struct pci_dev *pdev;
        unsigned int msix_entry_mask;
+       u32 irqvecs;
 };
 
 static inline struct device *aq_nic_get_dev(struct aq_nic_s *self)
index ecc6306f940f5d9f975d9cd422114f0be05c3435..a50e08bb4748386f999b1898b8207d973ac3508b 100644 (file)
@@ -267,16 +267,16 @@ static int aq_pci_probe(struct pci_dev *pdev,
        numvecs = min(numvecs, num_online_cpus());
        /*enable interrupts */
 #if !AQ_CFG_FORCE_LEGACY_INT
-       err = pci_alloc_irq_vectors(self->pdev, numvecs, numvecs,
-                                   PCI_IRQ_MSIX);
-
-       if (err < 0) {
-               err = pci_alloc_irq_vectors(self->pdev, 1, 1,
-                                           PCI_IRQ_MSI | PCI_IRQ_LEGACY);
-               if (err < 0)
-                       goto err_hwinit;
+       numvecs = pci_alloc_irq_vectors(self->pdev, 1, numvecs,
+                                       PCI_IRQ_MSIX | PCI_IRQ_MSI |
+                                       PCI_IRQ_LEGACY);
+
+       if (numvecs < 0) {
+               err = numvecs;
+               goto err_hwinit;
        }
 #endif
+       self->irqvecs = numvecs;
 
        /* net device init */
        aq_nic_cfg_start(self);
@@ -298,9 +298,9 @@ static int aq_pci_probe(struct pci_dev *pdev,
        kfree(self->aq_hw);
 err_ioremap:
        free_netdev(ndev);
-err_pci_func:
-       pci_release_regions(pdev);
 err_ndev:
+       pci_release_regions(pdev);
+err_pci_func:
        pci_disable_device(pdev);
        return err;
 }