Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a09bd81b authored by Igor Russkikh's avatar Igor Russkikh Committed by David S. Miller
Browse files

net: aquantia: Limit number of vectors to actually allocated irqs



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: default avatarLong, Nicholas <nicholas.a.long@baesystems.com>
Fixes: 23ee07ad ("net: aquantia: Cleanup pci functions module")
Signed-off-by: default avatarIgor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8c61ab7f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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)
+10 −10
Original line number Diff line number Diff line
@@ -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);
	numvecs = pci_alloc_irq_vectors(self->pdev, 1, numvecs,
					PCI_IRQ_MSIX | PCI_IRQ_MSI |
					PCI_IRQ_LEGACY);

	if (err < 0) {
		err = pci_alloc_irq_vectors(self->pdev, 1, 1,
					    PCI_IRQ_MSI | PCI_IRQ_LEGACY);
		if (err < 0)
	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;
}