Some platforms (such as LoongArch) cannot provide enough irq numbers as many as logical cpu numbers. So we should limit pci irq numbers when allocate msi/msix vectors, otherwise some device drivers may fail at initialization. This patch add a cmdline parameter "pci_irq_limit=xxxx" to control the limit. The default pci msi/msix number limit is defined 32 for LoongArch and NR_IRQS for other platforms. Signed-off-by: Juxin Gao <gaojuxin@xxxxxxxxxxx> Signed-off-by: Huacai Chen <chenhuacai@xxxxxxxxxxx> --- drivers/pci/msi/msi.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index ef1d8857a51b..6617381e50e7 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -402,12 +402,34 @@ static int msi_capability_init(struct pci_dev *dev, int nvec, return ret; } +#ifdef CONFIG_LOONGARCH +#define DEFAULT_PCI_IRQ_LIMITS 32 +#else +#define DEFAULT_PCI_IRQ_LIMITS NR_IRQS +#endif + +static int pci_irq_limits = DEFAULT_PCI_IRQ_LIMITS; + +static int __init pci_irq_limit(char *str) +{ + get_option(&str, &pci_irq_limits); + + if (pci_irq_limits == 0) + pci_irq_limits = DEFAULT_PCI_IRQ_LIMITS; + + return 0; +} + +early_param("pci_irq_limit", pci_irq_limit); + int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, struct irq_affinity *affd) { int nvec; int rc; + maxvec = clamp_val(maxvec, 0, pci_irq_limits); + if (!pci_msi_supported(dev, minvec) || dev->current_state != PCI_D0) return -EINVAL; @@ -776,7 +798,9 @@ static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *en int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec, struct irq_affinity *affd, int flags) { - int hwsize, rc, nvec = maxvec; + int hwsize, rc, nvec; + + nvec = clamp_val(maxvec, 0, pci_irq_limits); if (maxvec < minvec) return -ERANGE; -- 2.39.1