linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4] PCI: Prevent power state transition of erroneous device
@ 2025-05-19 10:28 Raag Jadav
  2025-05-19 10:41 ` Raag Jadav
  0 siblings, 1 reply; 27+ messages in thread
From: Raag Jadav @ 2025-05-19 10:28 UTC (permalink / raw)
  To: rafael, mahesh, oohall, bhelgaas
  Cc: linux-pci, linux-pm, linux-kernel, ilpo.jarvinen, lukas,
	aravind.iddamsetty, superm1, benato.denis96, Raag Jadav

If error status is set on an AER capable device, most likely either the
device recovery is in progress or has already failed. Neither of the
cases are well suited for power state transition of the device, since
this can lead to unpredictable consequences like resume failure, or in
worst case the device is lost because of it. Leave the device in its
existing power state to avoid such issues.

Signed-off-by: Raag Jadav <raag.jadav@intel.com>
---

v2: Synchronize AER handling with PCI PM (Rafael)
v3: Move pci_aer_in_progress() to pci_set_low_power_state() (Rafael)
    Elaborate "why" (Bjorn)
v4: Rely on error status instead of device status
    Condense comment (Lukas)

More discussion on [1].
[1] https://lore.kernel.org/all/CAJZ5v0g-aJXfVH+Uc=9eRPuW08t-6PwzdyMXsC6FZRKYJtY03Q@mail.gmail.com/

 drivers/pci/pci.c      |  9 +++++++++
 drivers/pci/pcie/aer.c | 13 +++++++++++++
 include/linux/aer.h    |  2 ++
 3 files changed, 24 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 4d7c9f64ea24..a20018692933 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/aer.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/dmi.h>
@@ -1539,6 +1540,14 @@ static int pci_set_low_power_state(struct pci_dev *dev, pci_power_t state, bool
 	   || (state == PCI_D2 && !dev->d2_support))
 		return -EIO;
 
+	/*
+	 * If error status is set on an AER capable device, it is not well
+	 * suited for power state transition. Leave it in its existing power
+	 * state to avoid issues like unpredictable resume failure.
+	 */
+	if (pci_aer_in_progress(dev))
+		return -EIO;
+
 	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
 	if (PCI_POSSIBLE_ERROR(pmcsr)) {
 		pci_err(dev, "Unable to change power state from %s to %s, device inaccessible\n",
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index a1cf8c7ef628..617fbac0d38a 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -237,6 +237,19 @@ int pcie_aer_is_native(struct pci_dev *dev)
 }
 EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, "CXL");
 
+bool pci_aer_in_progress(struct pci_dev *dev)
+{
+	int aer = dev->aer_cap;
+	u32 cor, uncor;
+
+	if (!pcie_aer_is_native(dev))
+		return false;
+
+	pci_read_config_dword(dev, aer + PCI_ERR_COR_STATUS, &cor);
+	pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS, &uncor);
+	return cor || uncor;
+}
+
 static int pci_enable_pcie_error_reporting(struct pci_dev *dev)
 {
 	int rc;
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 02940be66324..e6a380bb2e68 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -56,12 +56,14 @@ struct aer_capability_regs {
 #if defined(CONFIG_PCIEAER)
 int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
 int pcie_aer_is_native(struct pci_dev *dev);
+bool pci_aer_in_progress(struct pci_dev *dev);
 #else
 static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
 {
 	return -EINVAL;
 }
 static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }
+static inline bool pci_aer_in_progress(struct pci_dev *dev) { return false; }
 #endif
 
 void pci_print_aer(struct pci_dev *dev, int aer_severity,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2025-06-20 12:14 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-19 10:28 [PATCH v4] PCI: Prevent power state transition of erroneous device Raag Jadav
2025-05-19 10:41 ` Raag Jadav
2025-05-19 21:42   ` Denis Benato
2025-05-20  9:48     ` Raag Jadav
2025-05-20 15:23       ` Mario Limonciello
2025-05-20 15:47         ` Raag Jadav
2025-05-20 15:49           ` Mario Limonciello
2025-05-20 17:22             ` Denis Benato
2025-05-20 17:39               ` Mario Limonciello
2025-05-20 18:42                 ` Raag Jadav
2025-05-20 18:56                   ` Mario Limonciello
2025-05-21  8:54                     ` Raag Jadav
2025-05-21 11:27                       ` Rafael J. Wysocki
2025-05-23 15:23                         ` Rafael J. Wysocki
2025-05-30 17:23                           ` Raag Jadav
2025-05-30 17:49                             ` Rafael J. Wysocki
2025-06-04 15:42                               ` Raag Jadav
2025-06-04 18:19                                 ` Rafael J. Wysocki
2025-06-05 11:44                                   ` Raag Jadav
2025-06-05 12:26                                     ` Rafael J. Wysocki
2025-06-10 13:44                                       ` Raag Jadav
2025-06-10 13:53                                         ` Rafael J. Wysocki
2025-06-20 12:14                                           ` Raag Jadav
2025-05-21 13:39               ` Lukas Wunner
2025-05-21 17:06                 ` Mario Limonciello
2025-05-21 20:28                   ` Denis Benato
2025-05-22  7:31                     ` Lukas Wunner

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).