[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250809043409.wLu40x1p@linutronix.de>
Date: Sat, 9 Aug 2025 06:34:29 +0200
From: Nam Cao <namcao@...utronix.de>
To: Ammar Faizi <ammarfaizi2@...weeb.org>
Cc: Thomas Gleixner <tglx@...utronix.de>, Lukas Wunner <lukas@...ner.de>,
Bjorn Helgaas <helgaas@...nel.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Linux PCI Mailing List <linux-pci@...r.kernel.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
Rob Herring <robh@...nel.org>,
Lorenzo Pieralisi <lorenzo.pieralisi@....com>,
Manivannan Sadhasivam <mani@...nel.org>,
Krzysztof Wilczynski <kwilczynski@...nel.org>,
Armando Budianto <sprite@...weeb.org>,
Alviro Iskandar Setiawan <alviro.iskandar@...weeb.org>,
gwml@...r.gnuweeb.org, namcaov@...il.com
Subject: Re: [GIT PULL v2] PCI changes for v6.17
On Sat, Aug 09, 2025 at 07:52:30AM +0900, Ammar Faizi wrote:
> I can do that. Send me a git diff. I'll test it and back with the dmesg
> output.
That would be very helpful, thanks!
Please bear with me, this may take a few iterations.
Let's first try the below.
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index 9bbb0ff4cc15..ce477c030990 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -304,11 +304,14 @@ static bool vmd_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
struct irq_domain *real_parent,
struct msi_domain_info *info)
{
+ pr_err("%s: bus_token=%d\n", __func__, (int)info->bus_token);
if (WARN_ON_ONCE(info->bus_token != DOMAIN_BUS_PCI_DEVICE_MSIX))
return false;
- if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
+ if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) {
+ pr_err("%s:%d err=msi_lib_init\n", __func__, __LINE__);
return false;
+ }
info->chip->irq_enable = vmd_pci_msi_enable;
info->chip->irq_disable = vmd_pci_msi_disable;
diff --git a/drivers/pci/msi/api.c b/drivers/pci/msi/api.c
index 818d55fbad0d..e5f83036d76f 100644
--- a/drivers/pci/msi/api.c
+++ b/drivers/pci/msi/api.c
@@ -265,6 +265,7 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,
}
if (flags & PCI_IRQ_MSIX) {
+ pci_err(dev, "%s:%d msix\n", __func__, __LINE__);
nvecs = __pci_enable_msix_range(dev, NULL, min_vecs, max_vecs,
affd, flags);
if (nvecs > 0)
@@ -272,6 +273,7 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,
}
if (flags & PCI_IRQ_MSI) {
+ pci_err(dev, "%s:%d msi\n", __func__, __LINE__);
nvecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, affd);
if (nvecs > 0)
return nvecs;
@@ -279,6 +281,7 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,
/* use INTx IRQ if allowed */
if (flags & PCI_IRQ_INTX) {
+ pci_err(dev, "%s:%d INTx\n", __func__, __LINE__);
if (min_vecs == 1 && dev->irq) {
/*
* Invoke the affinity spreading logic to ensure that
diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c
index 0938ef7ebabf..6695508e9e53 100644
--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -13,8 +13,10 @@ int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
struct irq_domain *domain;
domain = dev_get_msi_domain(&dev->dev);
- if (domain && irq_domain_is_hierarchy(domain))
+ if (domain && irq_domain_is_hierarchy(domain)) {
+ pci_err(dev, "%s:%d err=\n", __func__, __LINE__);
return msi_domain_alloc_irqs_all_locked(&dev->dev, MSI_DEFAULT_DOMAIN, nvec);
+ }
return pci_msi_legacy_setup_msi_irqs(dev, nvec, type);
}
@@ -355,6 +357,7 @@ bool pci_msi_domain_supports(struct pci_dev *pdev, unsigned int feature_mask,
if (!domain || !irq_domain_is_hierarchy(domain)) {
if (IS_ENABLED(CONFIG_PCI_MSI_ARCH_FALLBACKS))
return mode == ALLOW_LEGACY;
+ pci_err(pdev, "%s:%d err\n", __func__, __LINE__);
return false;
}
@@ -364,6 +367,7 @@ bool pci_msi_domain_supports(struct pci_dev *pdev, unsigned int feature_mask,
* msi_domain_info::flags is the authoritative source of
* information.
*/
+ pci_err(pdev, "%s:%d not msi parent\n", __func__, __LINE__);
info = domain->host_data;
supported = info->flags;
} else {
@@ -374,6 +378,7 @@ bool pci_msi_domain_supports(struct pci_dev *pdev, unsigned int feature_mask,
* per device domain because the parent is never
* expanding the PCI/MSI functionality.
*/
+ pci_err(pdev, "%s:%d is msi parent\n", __func__, __LINE__);
supported = domain->msi_parent_ops->supported_flags;
}
diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
index 34d664139f48..028281d51fd0 100644
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -31,19 +31,25 @@ static int pci_msi_supported(struct pci_dev *dev, int nvec)
struct pci_bus *bus;
/* MSI must be globally enabled and supported by the device */
- if (!pci_msi_enable)
+ if (!pci_msi_enable) {
+ pci_err(dev, "%s:%d err=pci_msi_enable\n", __func__, __LINE__);
return 0;
+ }
- if (!dev || dev->no_msi)
+ if (!dev || dev->no_msi) {
+ pci_err(dev, "%s:%d err=no_msi\n", __func__, __LINE__);
return 0;
+ }
/*
* You can't ask to have 0 or less MSIs configured.
* a) it's stupid ..
* b) the list manipulation code assumes nvec >= 1.
*/
- if (nvec < 1)
+ if (nvec < 1) {
+ pci_err(dev, "%s:%d err=nvec\n", __func__, __LINE__);
return 0;
+ }
/*
* Any bridge which does NOT route MSI transactions from its
@@ -60,8 +66,10 @@ static int pci_msi_supported(struct pci_dev *dev, int nvec)
* at probe time.
*/
for (bus = dev->bus; bus; bus = bus->parent)
- if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+ if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) {
+ pci_err(dev, "%s:%d bus_flags\n", __func__, __LINE__);
return 0;
+ }
return 1;
}
@@ -86,8 +94,10 @@ static int pcim_setup_msi_release(struct pci_dev *dev)
return 0;
ret = devm_add_action(&dev->dev, pcim_msi_release, dev);
- if (ret)
+ if (ret) {
+ pci_err(dev, "%s:%d err=%d\n", __func__, __LINE__, ret);
return ret;
+ }
dev->is_msi_managed = true;
return 0;
@@ -671,17 +681,23 @@ static int __msix_setup_interrupts(struct pci_dev *__dev, struct msix_entry *ent
struct pci_dev *dev __free(free_msi_irqs) = __dev;
int ret = msix_setup_msi_descs(dev, entries, nvec, masks);
- if (ret)
+ if (ret) {
+ pci_err(dev, "%s:%d err=%d\n", __func__, __LINE__, ret);
return ret;
+ }
ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
- if (ret)
+ if (ret) {
+ pci_err(dev, "%s:%d err=%d\n", __func__, __LINE__, ret);
return ret;
+ }
/* Check if all MSI entries honor device restrictions */
ret = msi_verify_entries(dev);
- if (ret)
+ if (ret) {
+ pci_err(dev, "%s:%d err=%d\n", __func__, __LINE__, ret);
return ret;
+ }
msix_update_entries(dev, entries);
retain_and_null_ptr(dev);
@@ -736,8 +752,10 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
}
ret = msix_setup_interrupts(dev, entries, nvec, affd);
- if (ret)
+ if (ret) {
+ pci_err(dev, "%s:%d err=setup irqs\n", __func__, __LINE__);
goto out_disable;
+ }
/* Disable INTX */
pci_intx_for_msi(dev, 0);
@@ -793,30 +811,40 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int
{
int hwsize, rc, nvec = maxvec;
- if (maxvec < minvec)
+ if (maxvec < minvec) {
+ pci_err(dev, "%s:%d err=%d\n", __func__, __LINE__, -ERANGE);
return -ERANGE;
+ }
if (dev->msi_enabled) {
- pci_info(dev, "can't enable MSI-X (MSI already enabled)\n");
+ pci_err(dev, "can't enable MSI-X (MSI already enabled)\n");
return -EINVAL;
}
- if (WARN_ON_ONCE(dev->msix_enabled))
+ if (WARN_ON_ONCE(dev->msix_enabled)) {
+ pci_err(dev, "%s:%d err=%d\n", __func__, __LINE__, -EINVAL);
return -EINVAL;
+ }
/* Check MSI-X early on irq domain enabled architectures */
- if (!pci_msi_domain_supports(dev, MSI_FLAG_PCI_MSIX, ALLOW_LEGACY))
+ if (!pci_msi_domain_supports(dev, MSI_FLAG_PCI_MSIX, ALLOW_LEGACY)) {
+ pci_err(dev, "%s:%d err=ENOTSUPP\n", __func__, __LINE__);
return -ENOTSUPP;
+ }
if (!pci_msi_supported(dev, nvec) || dev->current_state != PCI_D0)
return -EINVAL;
hwsize = pci_msix_vec_count(dev);
- if (hwsize < 0)
+ if (hwsize < 0) {
+ pci_err(dev, "%s:%d err=hwsize\n", __func__, __LINE__);
return hwsize;
+ }
- if (!pci_msix_validate_entries(dev, entries, nvec))
+ if (!pci_msix_validate_entries(dev, entries, nvec)) {
+ pci_err(dev, "%s:%d err=validate entries\n", __func__, __LINE__);
return -EINVAL;
+ }
if (hwsize < nvec) {
/* Keep the IRQ virtual hackery working */
@@ -826,21 +854,27 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int
nvec = hwsize;
}
- if (nvec < minvec)
+ if (nvec < minvec) {
+ pci_err(dev, "%s:%d err=ENOSPC\n", __func__, __LINE__);
return -ENOSPC;
+ }
rc = pci_setup_msi_context(dev);
if (rc)
return rc;
- if (!pci_setup_msix_device_domain(dev, hwsize))
+ if (!pci_setup_msix_device_domain(dev, hwsize)) {
+ pci_err(dev, "%s:%d err=%d\n", __func__, __LINE__, -ENODEV);
return -ENODEV;
+ }
for (;;) {
if (affd) {
nvec = irq_calc_affinity_vectors(minvec, nvec, affd);
- if (nvec < minvec)
+ if (nvec < minvec) {
+ pci_err(dev, "%s:%d err=%d\n", __func__, __LINE__, -ENOSPC);
return -ENOSPC;
+ }
}
rc = msix_capability_init(dev, entries, nvec, affd);
diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index d1b68c18444f..44d1c0cd79fa 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -190,6 +190,7 @@ static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
goto intx_irq;
/* Try to use MSI-X or MSI if supported */
+ pr_err("%s:%d\n", __func__, __LINE__);
if (pcie_port_enable_irq_vec(dev, irqs, mask) == 0)
return 0;
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index dc473faadcc8..1771b6a24765 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -229,13 +229,17 @@ static struct irq_domain *__irq_domain_create(const struct irq_domain_info *info
if (WARN_ON((info->size && info->direct_max) ||
(!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && info->direct_max) ||
- (info->direct_max && info->direct_max != info->hwirq_max)))
+ (info->direct_max && info->direct_max != info->hwirq_max))) {
+ pr_err("%s:%d\n err", __func__, __LINE__);
return ERR_PTR(-EINVAL);
+ }
domain = kzalloc_node(struct_size(domain, revmap, info->size),
GFP_KERNEL, of_node_to_nid(to_of_node(info->fwnode)));
- if (!domain)
+ if (!domain) {
+ pr_err("%s:%d\n err", __func__, __LINE__);
return ERR_PTR(-ENOMEM);
+ }
err = irq_domain_set_name(domain, info);
if (err) {
@@ -328,14 +332,18 @@ static struct irq_domain *__irq_domain_instantiate(const struct irq_domain_info
if (info->dgc_info) {
err = irq_domain_alloc_generic_chips(domain, info->dgc_info);
- if (err)
+ if (err) {
+ pr_err("%s:%d\n err=%d", __func__, __LINE__, err);
goto err_domain_free;
+ }
}
if (info->init) {
err = info->init(domain);
- if (err)
+ if (err) {
+ pr_err("%s:%d\n err=%d", __func__, __LINE__, err);
goto err_domain_gc_remove;
+ }
}
__irq_domain_publish(domain);
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index 9b09ad3f9914..b86ed78be575 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -316,11 +316,14 @@ int msi_setup_device_data(struct device *dev)
return 0;
md = devres_alloc(msi_device_data_release, sizeof(*md), GFP_KERNEL);
- if (!md)
+ if (!md) {
+ dev_err(dev, "%s:%d err=ENOMEM\n", __func__, __LINE__);
return -ENOMEM;
+ }
ret = msi_sysfs_create_group(dev);
if (ret) {
+ dev_err(dev, "%s:%d err=%d\n", __func__, __LINE__, ret);
devres_free(md);
return ret;
}
@@ -1035,16 +1038,22 @@ bool msi_create_device_irq_domain(struct device *dev, unsigned int domid,
const struct msi_parent_ops *pops;
struct fwnode_handle *fwnode;
- if (!irq_domain_is_msi_parent(parent))
+ if (!irq_domain_is_msi_parent(parent)) {
+ dev_err(dev, "%s:%d err=not parent\n", __func__, __LINE__);
return false;
+ }
- if (domid >= MSI_MAX_DEVICE_IRQDOMAINS)
+ if (domid >= MSI_MAX_DEVICE_IRQDOMAINS) {
+ dev_err(dev, "%s:%d err=max domain\n", __func__, __LINE__);
return false;
+ }
struct msi_domain_template *bundle __free(kfree) =
kmemdup(template, sizeof(*bundle), GFP_KERNEL);
- if (!bundle)
+ if (!bundle) {
+ dev_err(dev, "%s:%d err=mem\n", __func__, __LINE__);
return false;
+ }
bundle->info.hwsize = hwsize;
bundle->info.chip = &bundle->chip;
@@ -1077,23 +1086,32 @@ bool msi_create_device_irq_domain(struct device *dev, unsigned int domid,
if (!fwnode)
return false;
- if (msi_setup_device_data(dev))
+ if (msi_setup_device_data(dev)) {
+ dev_err(dev, "%s:%d err=setup\n", __func__, __LINE__);
return false;
+ }
guard(msi_descs_lock)(dev);
- if (WARN_ON_ONCE(msi_get_device_domain(dev, domid)))
+ if (WARN_ON_ONCE(msi_get_device_domain(dev, domid))) {
+ dev_err(dev, "%s:%d err=get domain\n", __func__, __LINE__);
return false;
+ }
- if (!pops->init_dev_msi_info(dev, parent, parent, &bundle->info))
+ if (!pops->init_dev_msi_info(dev, parent, parent, &bundle->info)) {
+ dev_err(dev, "%s:%d err=init_msi_info\n", __func__, __LINE__);
return false;
+ }
domain = __msi_create_irq_domain(fwnode, &bundle->info, IRQ_DOMAIN_FLAG_MSI_DEVICE, parent);
- if (!domain)
+ if (!domain) {
+ dev_err(dev, "%s:%d err=create domain\n", __func__, __LINE__);
return false;
+ }
dev->msi.data->__domains[domid].domain = domain;
if (msi_domain_prepare_irqs(domain, dev, hwsize, &bundle->alloc_info)) {
+ pr_err("%s:%d\n err=prepare_irqs", __func__, __LINE__);
dev->msi.data->__domains[domid].domain = NULL;
irq_domain_remove(domain);
return false;
Powered by blists - more mailing lists