linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Manivannan Sadhasivam via B4 Relay <devnull+manivannan.sadhasivam.linaro.org@kernel.org>
To: Bjorn Helgaas <bhelgaas@google.com>,
	 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	 Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
	 Johan Hovold <johan+linaro@kernel.org>,
	Abel Vesa <abel.vesa@linaro.org>,
	 Stephan Gerhold <stephan.gerhold@linaro.org>,
	 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
	 Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>,
	 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>,
	 stable+noautosel@kernel.org
Subject: [PATCH 3/5] PCI/pwrctl: Ensure that the pwrctl drivers are probed before the PCI client drivers
Date: Tue, 22 Oct 2024 15:57:31 +0530	[thread overview]
Message-ID: <20241022-pci-pwrctl-rework-v1-3-94a7e90f58c5@linaro.org> (raw)
In-Reply-To: <20241022-pci-pwrctl-rework-v1-0-94a7e90f58c5@linaro.org>

From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

As per the kernel device driver model, pwrctl device is the supplier for
the PCI device. But the device link that enforces the supplier-consumer
relationship is created inside the pwrctl driver currently. Due to this,
the driver model doesn't prevent probing of the PCI client drivers before
probing the corresponding pwrctl drivers. This may lead to a race condition
if the PCI device was already powered on by the bootloader (before the
pwrctl driver).

If the bootloader did not power on the PCI device, this wouldn't create any
problem as the pwrctl driver will be the one powering on the device, so the
PCI client driver always gets probed afterward. But if the device was
already powered on, then the device will be seen by the PCI core and the
PCI client driver may get probed before its pwrctl driver. This creates a
race condition as the pwrctl driver may change the device power state while
the device is being accessed by the client driver.

One such issue was already reported on the Qcom X13s platform with the
WLAN device and fixed with a hack in the WCN pwrseq driver by the 'commit
a9aaf1ff88a8 ("power: sequencing: request the WLAN enable GPIO as-is")'.

But a cleaner way to fix the above mentioned race condition would be to
ensure that the pwrctl drivers are always probed before the client drivers.
This is achieved by creating the device link between pwrctl device and PCI
device before device_attach() in pci_bus_add_device().

Note that there is no need to explicitly remove the device link as that
will be taken care by the driver core when the PCI device gets removed.

Cc: stable+noautosel@kernel.org # Depends on power supply check
Fixes: 4565d2652a37 ("PCI/pwrctl: Add PCI power control core code")
Fixes: 8fb18619d910 ("PCI/pwrctl: Create platform devices for child OF nodes of the port node")
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/pci/bus.c         | 26 +++++++++++++++++++-------
 drivers/pci/pwrctl/core.c | 10 ----------
 2 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 698ec98b9388..351af581904f 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -345,13 +345,6 @@ void pci_bus_add_device(struct pci_dev *dev)
 	pci_proc_attach_device(dev);
 	pci_bridge_d3_update(dev);
 
-	dev->match_driver = !dn || of_device_is_available(dn);
-	retval = device_attach(&dev->dev);
-	if (retval < 0 && retval != -EPROBE_DEFER)
-		pci_warn(dev, "device attach failed (%d)\n", retval);
-
-	pci_dev_assign_added(dev, true);
-
 	if (dev_of_node(&dev->dev) && pci_is_bridge(dev)) {
 		for_each_child_of_node_scoped(dn, child) {
 			/*
@@ -370,6 +363,25 @@ void pci_bus_add_device(struct pci_dev *dev)
 				pci_err(dev, "failed to create OF node: %s\n", child->name);
 		}
 	}
+
+	/*
+	 * Create a device link between the PCI device and pwrctl device (if
+	 * exists). This ensures that the pwrctl drivers are probed before the
+	 * PCI client drivers.
+	 */
+	pdev = of_find_device_by_node(dn);
+	if (pdev) {
+		if (!device_link_add(&dev->dev, &pdev->dev, DL_FLAG_AUTOREMOVE_CONSUMER))
+			pci_err(dev, "failed to add device link between %s and %s\n",
+				dev_name(&dev->dev), pdev->name);
+	}
+
+	dev->match_driver = !dn || of_device_is_available(dn);
+	retval = device_attach(&dev->dev);
+	if (retval < 0 && retval != -EPROBE_DEFER)
+		pci_warn(dev, "device attach failed (%d)\n", retval);
+
+	pci_dev_assign_added(dev, true);
 }
 EXPORT_SYMBOL_GPL(pci_bus_add_device);
 
diff --git a/drivers/pci/pwrctl/core.c b/drivers/pci/pwrctl/core.c
index 01d913b60316..bb5a23712434 100644
--- a/drivers/pci/pwrctl/core.c
+++ b/drivers/pci/pwrctl/core.c
@@ -33,16 +33,6 @@ static int pci_pwrctl_notify(struct notifier_block *nb, unsigned long action,
 		 */
 		dev->of_node_reused = true;
 		break;
-	case BUS_NOTIFY_BOUND_DRIVER:
-		pwrctl->link = device_link_add(dev, pwrctl->dev,
-					       DL_FLAG_AUTOREMOVE_CONSUMER);
-		if (!pwrctl->link)
-			dev_err(pwrctl->dev, "Failed to add device link\n");
-		break;
-	case BUS_NOTIFY_UNBOUND_DRIVER:
-		if (pwrctl->link)
-			device_link_remove(dev, pwrctl->dev);
-		break;
 	}
 
 	return NOTIFY_DONE;

-- 
2.25.1



  parent reply	other threads:[~2024-10-22 10:28 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-22 10:27 [PATCH 0/5] PCI/pwrctl: Ensure that the pwrctl drivers are probed before PCI client drivers Manivannan Sadhasivam via B4 Relay
2024-10-22 10:27 ` [PATCH 1/5] PCI/pwrctl: Use of_platform_device_create() to create pwrctl devices Manivannan Sadhasivam via B4 Relay
2024-10-23  9:18   ` Bartosz Golaszewski
2024-10-24 13:37     ` Manivannan Sadhasivam
2024-10-22 10:27 ` [PATCH 2/5] PCI/pwrctl: Create pwrctl devices only if at least one power supply is present Manivannan Sadhasivam via B4 Relay
2024-10-23  9:22   ` Bartosz Golaszewski
2024-10-22 10:27 ` Manivannan Sadhasivam via B4 Relay [this message]
2024-10-23 10:22   ` [PATCH 3/5] PCI/pwrctl: Ensure that the pwrctl drivers are probed before the PCI client drivers Bartosz Golaszewski
2024-10-22 10:27 ` [PATCH 4/5] PCI/pwrctl: Move pwrctl device creation to its own helper function Manivannan Sadhasivam via B4 Relay
2024-10-23 10:23   ` Bartosz Golaszewski
2024-10-25  8:04     ` Manivannan Sadhasivam
2024-10-25  8:06       ` Bartosz Golaszewski
2024-10-22 10:27 ` [PATCH 5/5] PCI/pwrctl: Remove pwrctl device without iterating over all children of pwrctl parent Manivannan Sadhasivam via B4 Relay
2024-10-23 10:25   ` Bartosz Golaszewski
2024-10-23 10:30 ` [PATCH 0/5] PCI/pwrctl: Ensure that the pwrctl drivers are probed before PCI client drivers Bartosz Golaszewski
2024-10-24 10:13   ` Krishna Chaitanya Chundru
2024-11-03 20:31 ` Krzysztof Wilczyński
2024-11-05  0:12   ` Bjorn Helgaas
2024-11-05  0:32     ` Krzysztof Wilczyński

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241022-pci-pwrctl-rework-v1-3-94a7e90f58c5@linaro.org \
    --to=devnull+manivannan.sadhasivam.linaro.org@kernel.org \
    --cc=abel.vesa@linaro.org \
    --cc=bartosz.golaszewski@linaro.org \
    --cc=bhelgaas@google.com \
    --cc=bjorn.andersson@oss.qualcomm.com \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=johan+linaro@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=manivannan.sadhasivam@linaro.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=stable+noautosel@kernel.org \
    --cc=stephan.gerhold@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).