[PATCH] PCI: dwc: Initialize pp->lock before MSI domain registration

Yadu M G posted 1 patch 4 hours ago
drivers/pci/controller/dwc/pcie-designware-host.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
[PATCH] PCI: dwc: Initialize pp->lock before MSI domain registration
Posted by Yadu M G 4 hours ago
A lockdep warning is observed during boot on a Qcom firmware managed
platform:

  INFO: trying to register non-static key.
  The code is fine but needs lockdep annotation, or maybe
  you didn't initialize this object before use?
  turning off the locking correctness validator.
  ...
  Call trace:
   register_lock_class+0x128/0x4d8
   __lock_acquire+0x110/0x1db0
   lock_acquire+0x278/0x3d8
   _raw_spin_lock_irq+0x6c/0xc0
   dw_pcie_irq_domain_alloc+0x48/0x190
   irq_domain_alloc_irqs_parent+0x2c/0x48
   msi_domain_alloc+0x90/0x160
  ...

dw_pcie_irq_domain_alloc() takes pp->lock while allocating MSI
interrupts. pp->lock was initialized in dw_pcie_host_init(). However,
some DWC glue drivers like those on Qcom firmware managed platforms
allocate MSI domains from their .msi_init callback by calling
dw_pcie_allocate_domains() directly, bypassing dw_pcie_host_init(). This
leaves pp->lock without a lockdep key and triggers the warning when MSI
vectors are later allocated.

Initialize pp->lock in dw_pcie_allocate_domains() immediately before
registering the MSI IRQ domain so the lock is always initialized for
every caller path.

Signed-off-by: Yadu M G <yadu.mg@oss.qualcomm.com>
---
 drivers/pci/controller/dwc/pcie-designware-host.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index c9517a348836..8acd671bbc8c 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -215,6 +215,14 @@ int dw_pcie_allocate_domains(struct dw_pcie_rp *pp)
 		.host_data	= pp,
 	};
 
+	/*
+	 * Initialize the lock here rather than in dw_pcie_host_init() so that
+	 * drivers using a custom msi_init() callback that call
+	 * dw_pcie_allocate_domains() directly also have the lock properly
+	 * initialized before dw_pcie_irq_domain_alloc() can be invoked.
+	 */
+	raw_spin_lock_init(&pp->lock);
+
 	pp->irq_domain = msi_create_parent_irq_domain(&info, &dw_pcie_msi_parent_ops);
 	if (!pp->irq_domain) {
 		dev_err(pci->dev, "Failed to create IRQ domain\n");
@@ -573,8 +581,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
 	struct pci_host_bridge *bridge;
 	int ret;
 
-	raw_spin_lock_init(&pp->lock);
-
 	bridge = devm_pci_alloc_host_bridge(dev, 0);
 	if (!bridge)
 		return -ENOMEM;
-- 
2.25.1