mirror of
https://github.com/torvalds/linux.git
synced 2025-11-01 17:18:25 +02:00
PCI/MSI: Size device MSI domain with the maximum number of vectors
Zenghui reports that since1396e89e09("genirq/msi: Move prepare() call to per-device allocation"), his Multi-MSI capable device isn't working anymore. This is a consequence of15c72f824b("PCI/MSI: Add support for per device MSI[X] domains"), which always creates a MSI domain of size 1, even in the presence of Multi-MSI. While this was somehow working until then, moving the .prepare() call ends up sizing the ITS table with a tiny value for this device, and making the endpoint driver unhappy. Instead, always create the domain and call the .prepare() helper with the maximum expected size. Fixes:1396e89e09("genirq/msi: Move prepare() call to per-device allocation") Fixes:15c72f824b("PCI/MSI: Add support for per device MSI[X] domains") Reported-by: Zenghui Yu <yuzenghui@huawei.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Zenghui Yu <yuzenghui@huawei.com> Reviewed-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Link: https://lore.kernel.org/all/20250603141801.915305-1-maz@kernel.org Closes: https://lore.kernel.org/r/0b1d7aec-1eac-a9cd-502a-339e216e08a1@huawei.com
This commit is contained in:
parent
5abc7438f1
commit
9cc82d99b1
3 changed files with 8 additions and 7 deletions
|
|
@ -271,6 +271,7 @@ static bool pci_create_device_domain(struct pci_dev *pdev, const struct msi_doma
|
|||
/**
|
||||
* pci_setup_msi_device_domain - Setup a device MSI interrupt domain
|
||||
* @pdev: The PCI device to create the domain on
|
||||
* @hwsize: The maximum number of MSI vectors
|
||||
*
|
||||
* Return:
|
||||
* True when:
|
||||
|
|
@ -287,7 +288,7 @@ static bool pci_create_device_domain(struct pci_dev *pdev, const struct msi_doma
|
|||
* - The device is removed
|
||||
* - MSI is disabled and a MSI-X domain is created
|
||||
*/
|
||||
bool pci_setup_msi_device_domain(struct pci_dev *pdev)
|
||||
bool pci_setup_msi_device_domain(struct pci_dev *pdev, unsigned int hwsize)
|
||||
{
|
||||
if (WARN_ON_ONCE(pdev->msix_enabled))
|
||||
return false;
|
||||
|
|
@ -297,7 +298,7 @@ bool pci_setup_msi_device_domain(struct pci_dev *pdev)
|
|||
if (pci_match_device_domain(pdev, DOMAIN_BUS_PCI_DEVICE_MSIX))
|
||||
msi_remove_device_irq_domain(&pdev->dev, MSI_DEFAULT_DOMAIN);
|
||||
|
||||
return pci_create_device_domain(pdev, &pci_msi_template, 1);
|
||||
return pci_create_device_domain(pdev, &pci_msi_template, hwsize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -439,16 +439,16 @@ int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
|
|||
if (nvec < minvec)
|
||||
return -ENOSPC;
|
||||
|
||||
if (nvec > maxvec)
|
||||
nvec = maxvec;
|
||||
|
||||
rc = pci_setup_msi_context(dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!pci_setup_msi_device_domain(dev))
|
||||
if (!pci_setup_msi_device_domain(dev, nvec))
|
||||
return -ENODEV;
|
||||
|
||||
if (nvec > maxvec)
|
||||
nvec = maxvec;
|
||||
|
||||
for (;;) {
|
||||
if (affd) {
|
||||
nvec = irq_calc_affinity_vectors(minvec, nvec, affd);
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ enum support_mode {
|
|||
};
|
||||
|
||||
bool pci_msi_domain_supports(struct pci_dev *dev, unsigned int feature_mask, enum support_mode mode);
|
||||
bool pci_setup_msi_device_domain(struct pci_dev *pdev);
|
||||
bool pci_setup_msi_device_domain(struct pci_dev *pdev, unsigned int hwsize);
|
||||
bool pci_setup_msix_device_domain(struct pci_dev *pdev, unsigned int hwsize);
|
||||
|
||||
/* Legacy (!IRQDOMAIN) fallbacks */
|
||||
|
|
|
|||
Loading…
Reference in a new issue