mirror of
https://github.com/torvalds/linux.git
synced 2025-11-03 18:20: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
|
* pci_setup_msi_device_domain - Setup a device MSI interrupt domain
|
||||||
* @pdev: The PCI device to create the domain on
|
* @pdev: The PCI device to create the domain on
|
||||||
|
* @hwsize: The maximum number of MSI vectors
|
||||||
*
|
*
|
||||||
* Return:
|
* Return:
|
||||||
* True when:
|
* True when:
|
||||||
|
|
@ -287,7 +288,7 @@ static bool pci_create_device_domain(struct pci_dev *pdev, const struct msi_doma
|
||||||
* - The device is removed
|
* - The device is removed
|
||||||
* - MSI is disabled and a MSI-X domain is created
|
* - 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))
|
if (WARN_ON_ONCE(pdev->msix_enabled))
|
||||||
return false;
|
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))
|
if (pci_match_device_domain(pdev, DOMAIN_BUS_PCI_DEVICE_MSIX))
|
||||||
msi_remove_device_irq_domain(&pdev->dev, MSI_DEFAULT_DOMAIN);
|
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)
|
if (nvec < minvec)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (nvec > maxvec)
|
|
||||||
nvec = maxvec;
|
|
||||||
|
|
||||||
rc = pci_setup_msi_context(dev);
|
rc = pci_setup_msi_context(dev);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!pci_setup_msi_device_domain(dev))
|
if (!pci_setup_msi_device_domain(dev, nvec))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (nvec > maxvec)
|
||||||
|
nvec = maxvec;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (affd) {
|
if (affd) {
|
||||||
nvec = irq_calc_affinity_vectors(minvec, nvec, 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_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);
|
bool pci_setup_msix_device_domain(struct pci_dev *pdev, unsigned int hwsize);
|
||||||
|
|
||||||
/* Legacy (!IRQDOMAIN) fallbacks */
|
/* Legacy (!IRQDOMAIN) fallbacks */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue