mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/4] PCI/DPC: Decide DPC ownership with host_bridge->native_dpc
@ 2026-10-07 16:58 Kuppuswamy Sathyanarayanan
  2026-10-07 16:58 ` [PATCH 1/4] PCI/EDR: Remove CONFIG_PCIE_EDR Kuppuswamy Sathyanarayanan
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-10-07 16:58 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rafael J . Wysocki, Lukas Wunner, Mahesh J Salgaonkar,
	Oliver O'Halloran, Len Brown, linux-pci, linux-acpi,
	linux-kernel

This series makes host_bridge->native_dpc the single decider for whether
Linux uses DPC, as Bjorn asked during the review of "Simplify PCIe native
ownership".

  https://lore.kernel.org/r/20261001221408.GA2731929@bhelgaas

Today the DPC service binds on host_bridge->native_aer, AER availability
and "pcie_ports=dpc-native".  host_bridge->native_dpc is only consulted
by pci_dpc_recovered().  After this series, native_dpc is the end result
of everything that decides DPC ownership, and portdrv binds the DPC
service on it.

The series applies on top of two others:

  - pci/portdrv, which has patches 1-3 of v15 of "Simplify PCIe native
    ownership".  They fold "pcie_ports=native" and "pcie_ports=dpc-native"
    into the _OSC control mask, so native_dpc already reflects the
    command line.

    https://lore.kernel.org/r/20261002211828.1293177-1-sathyanarayanan.kuppuswamy@linux.intel.com

  - Lukas's "Error reporting for AER-incapable devices".  It removes the
    AER Capability requirement from the DPC driver.

    https://lore.kernel.org/r/cover.1790531238.git.lukas@wunner.de

Patch 1 removes CONFIG_PCIE_EDR, which was another knob in deciding
whether to request DPC control in _OSC.

Patch 2 stops requiring pci_aer_available() to bind the DPC service,
since the DPC driver does not depend on MSI or on the AER driver.

Patch 3 requests DPC control only together with AER control, as PCI
Firmware r3.3, sec 4.5.2.4, requires.

Patch 4 binds the DPC service on host_bridge->native_dpc and logs a
message when the OS assumes DPC control that _OSC did not grant.

Kuppuswamy Sathyanarayanan (4):
  PCI/EDR: Remove CONFIG_PCIE_EDR
  PCI/portdrv: Don't require AER to bind DPC service
  PCI/ACPI: Request DPC control only together with AER control
  PCI/portdrv: Bind DPC service based on host_bridge->native_dpc

 drivers/acpi/pci_root.c    | 26 +++++++++++++++++++++++---
 drivers/pci/pcie/Kconfig   |  9 ---------
 drivers/pci/pcie/Makefile  |  5 ++++-
 drivers/pci/pcie/dpc.c     |  5 +++--
 drivers/pci/pcie/portdrv.c |  7 +------
 include/linux/pci-acpi.h   |  4 ++--
 6 files changed, 33 insertions(+), 23 deletions(-)


base-commit: 4fe37866b0d92cdc45b62954a76489a9d9f8bd73
prerequisite-patch-id: e0eafcb39f15c38f3acfa601dfce07a6f0832ce1
prerequisite-patch-id: 83e8185612e785fad80790d4a0c20fa68ab12ce7
prerequisite-patch-id: 8e9e2b06f55249ff57c7d7f43918ee82f79d1450
prerequisite-patch-id: 78ad13a1c423c3ee50122237c4bd0fdedf2d1e00
prerequisite-patch-id: 0c4b9d46eea86635c431382aef2bf576a3bb5691
prerequisite-patch-id: 2d1a35309e750427352c6fe0d9bb62c4453c6252
prerequisite-patch-id: c1ed9c8ac6123e0a65ae0d7ba3183dd46477edf7
-- 
2.43.0


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

* [PATCH 1/4] PCI/EDR: Remove CONFIG_PCIE_EDR
  2026-10-07 16:58 [PATCH 0/4] PCI/DPC: Decide DPC ownership with host_bridge->native_dpc Kuppuswamy Sathyanarayanan
@ 2026-10-07 16:58 ` Kuppuswamy Sathyanarayanan
  2026-10-07 16:58 ` [PATCH 2/4] PCI/portdrv: Don't require AER to bind DPC service Kuppuswamy Sathyanarayanan
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-10-07 16:58 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rafael J . Wysocki, Lukas Wunner, Mahesh J Salgaonkar,
	Oliver O'Halloran, Len Brown, linux-pci, linux-acpi,
	linux-kernel

Error Disconnect Recover (EDR) is the ACPI half of the hybrid DPC model,
where firmware owns DPC and notifies the OS of containment events.

CONFIG_PCIE_EDR made EDR optional on top of CONFIG_PCIE_DPC.  This adds
another knob to the decision to request DPC control in _OSC.  The OS
requests DPC control only if it also supports EDR, so with
CONFIG_PCIE_EDR=n it never requests DPC control.  There is little reason
to build DPC without EDR on ACPI systems.

Remove the option and build edr.c whenever CONFIG_PCIE_DPC and
CONFIG_ACPI are both enabled.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
 drivers/acpi/pci_root.c   | 6 +++---
 drivers/pci/pcie/Kconfig  | 9 ---------
 drivers/pci/pcie/Makefile | 5 ++++-
 drivers/pci/pcie/dpc.c    | 5 +++--
 include/linux/pci-acpi.h  | 4 ++--
 5 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index a1a9c06012f8..b0e0b33e3254 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -438,7 +438,7 @@ static u32 calculate_support(void)
 		support |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT;
 	if (pci_msi_enabled())
 		support |= OSC_PCI_MSI_SUPPORT;
-	if (IS_ENABLED(CONFIG_PCIE_EDR))
+	if (IS_ENABLED(CONFIG_PCIE_DPC))
 		support |= OSC_PCI_EDR_SUPPORT;
 
 	return support;
@@ -515,9 +515,9 @@ static u32 calculate_control(void)
 	 * Per the Downstream Port Containment Related Enhancements ECN to
 	 * the PCI Firmware Spec, r3.2, sec 4.5.1, table 4-5,
 	 * OSC_PCI_EXPRESS_DPC_CONTROL indicates the OS supports both DPC
-	 * and EDR.
+	 * and EDR.  EDR is always built with DPC on ACPI systems.
 	 */
-	if (IS_ENABLED(CONFIG_PCIE_DPC) && IS_ENABLED(CONFIG_PCIE_EDR))
+	if (IS_ENABLED(CONFIG_PCIE_DPC))
 		control |= OSC_PCI_EXPRESS_DPC_CONTROL;
 
 	return control;
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index 207c2deae35f..de4ea33b4524 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -137,12 +137,3 @@ config PCIE_PTM
 	  This is only useful if you have devices that support PTM, but it
 	  is safe to enable even if you don't.
 
-config PCIE_EDR
-	bool "PCI Express Error Disconnect Recover support"
-	depends on PCIE_DPC && ACPI
-	help
-	  This option adds Error Disconnect Recover support as specified
-	  in the Downstream Port Containment Related Enhancements ECN to
-	  the PCI Firmware Specification r3.2.  Enable this if you want to
-	  support hybrid DPC model which uses both firmware and OS to
-	  implement DPC.
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index b0b43a18c304..46b24311f659 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -13,4 +13,7 @@ obj-$(CONFIG_PCIEAER_INJECT)	+= aer_inject.o
 obj-$(CONFIG_PCIE_PME)		+= pme.o
 obj-$(CONFIG_PCIE_DPC)		+= dpc.o
 obj-$(CONFIG_PCIE_PTM)		+= ptm.o
-obj-$(CONFIG_PCIE_EDR)		+= edr.o
+
+ifdef CONFIG_ACPI
+obj-$(CONFIG_PCIE_DPC)		+= edr.o
+endif
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index fdea3db61a4a..b4fb45ca559d 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -109,10 +109,11 @@ bool pci_dpc_recovered(struct pci_dev *pdev)
 
 	/*
 	 * Synchronization between hotplug and DPC is not supported
-	 * if DPC is owned by firmware and EDR is not enabled.
+	 * if DPC is owned by firmware and there is no EDR, i.e., on
+	 * non-ACPI systems.
 	 */
 	host = pci_find_host_bridge(pdev->bus);
-	if (!host->native_dpc && !IS_ENABLED(CONFIG_PCIE_EDR))
+	if (!host->native_dpc && !IS_ENABLED(CONFIG_ACPI))
 		return false;
 
 	/*
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index c0c54baadf04..9715351c0d51 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -123,13 +123,13 @@ extern const guid_t pci_acpi_dsm_guid;
 #define DSM_PCI_POWER_ON_RESET_DELAY		0x08
 #define DSM_PCI_DEVICE_READINESS_DURATIONS	0x09
 
-#ifdef CONFIG_PCIE_EDR
+#ifdef CONFIG_PCIE_DPC
 void pci_acpi_add_edr_notifier(struct pci_dev *pdev);
 void pci_acpi_remove_edr_notifier(struct pci_dev *pdev);
 #else
 static inline void pci_acpi_add_edr_notifier(struct pci_dev *pdev) { }
 static inline void pci_acpi_remove_edr_notifier(struct pci_dev *pdev) { }
-#endif /* CONFIG_PCIE_EDR */
+#endif /* CONFIG_PCIE_DPC */
 
 int pci_acpi_set_companion_lookup_hook(struct acpi_device *(*func)(struct pci_dev *));
 void pci_acpi_clear_companion_lookup_hook(void);
-- 
2.43.0


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

* [PATCH 2/4] PCI/portdrv: Don't require AER to bind DPC service
  2026-10-07 16:58 [PATCH 0/4] PCI/DPC: Decide DPC ownership with host_bridge->native_dpc Kuppuswamy Sathyanarayanan
  2026-10-07 16:58 ` [PATCH 1/4] PCI/EDR: Remove CONFIG_PCIE_EDR Kuppuswamy Sathyanarayanan
@ 2026-10-07 16:58 ` Kuppuswamy Sathyanarayanan
  2026-10-07 16:58 ` [PATCH 3/4] PCI/ACPI: Request DPC control only together with AER control Kuppuswamy Sathyanarayanan
  2026-10-07 16:58 ` [PATCH 4/4] PCI/portdrv: Bind DPC service based on host_bridge->native_dpc Kuppuswamy Sathyanarayanan
  3 siblings, 0 replies; 5+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-10-07 16:58 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rafael J . Wysocki, Lukas Wunner, Mahesh J Salgaonkar,
	Oliver O'Halloran, Len Brown, linux-pci, linux-acpi,
	linux-kernel

get_port_device_capability() binds the DPC service only if
pci_aer_available() is true.  pci_aer_available() is false with
"pci=noaer" or when MSI is disabled.

The DPC driver does not need either of these.  pci_aer_available()
depends on MSI only because the AER driver does not work with INTx
(commit 3e77a3f7895e ("PCI: Disable AER with pci=nomsi")).  The DPC
driver does not depend on MSI or on the AER driver, and it works on
ports without an AER capability.

PCIe r7.0 sec 6.2.11 recommends that the OS link control of DPC to
control of AER.  PCI Firmware r3.3, sec 4.5.2.4, requires the same for
_OSC.  Both are about ownership, not about using the AER driver.
host->native_aer and the _OSC negotiation already cover ownership.

Drop the pci_aer_available() check.

The changes in behavior are:

  - ACPI systems booted with "pci=noaer" or with MSI disabled, and with
    "pcie_ports=native" or "pcie_ports=dpc-native".  The OS now uses DPC
    there, which is what those options ask for.  Without them nothing
    changes, because the OS does not request AER control in _OSC, so
    host->native_aer is not set.

  - Non-ACPI systems booted with "pci=noaer" or with MSI disabled.
    host->native_aer is set there, so the OS now uses DPC.  An
    uncorrectable error that used to be ignored with "pci=noaer" now
    triggers DPC, which takes the link down and resets the devices below
    the port.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
 drivers/pci/pcie/portdrv.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index 32fc623dd410..b77680fd3b75 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -263,7 +263,6 @@ static int get_port_device_capability(struct pci_dev *dev)
 	 * permission to use AER.
 	 */
 	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC) &&
-	    pci_aer_available() &&
 	    (pcie_ports_dpc_native || host->native_aer))
 		services |= PCIE_PORT_SERVICE_DPC;
 
-- 
2.43.0


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

* [PATCH 3/4] PCI/ACPI: Request DPC control only together with AER control
  2026-10-07 16:58 [PATCH 0/4] PCI/DPC: Decide DPC ownership with host_bridge->native_dpc Kuppuswamy Sathyanarayanan
  2026-10-07 16:58 ` [PATCH 1/4] PCI/EDR: Remove CONFIG_PCIE_EDR Kuppuswamy Sathyanarayanan
  2026-10-07 16:58 ` [PATCH 2/4] PCI/portdrv: Don't require AER to bind DPC service Kuppuswamy Sathyanarayanan
@ 2026-10-07 16:58 ` Kuppuswamy Sathyanarayanan
  2026-10-07 16:58 ` [PATCH 4/4] PCI/portdrv: Bind DPC service based on host_bridge->native_dpc Kuppuswamy Sathyanarayanan
  3 siblings, 0 replies; 5+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-10-07 16:58 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rafael J . Wysocki, Lukas Wunner, Mahesh J Salgaonkar,
	Oliver O'Halloran, Len Brown, linux-pci, linux-acpi,
	linux-kernel

PCI Firmware r3.3, sec 4.5.2.4, requires the OS to request AER control
when it requests DPC control.  calculate_control() requests DPC control
whenever CONFIG_PCIE_DPC is enabled, even if it does not request AER
control, e.g., with "pci=noaer" or when MSI is disabled.

Request DPC control only if AER control is also requested.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
 drivers/acpi/pci_root.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b0e0b33e3254..5c674d5b6bb8 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -516,8 +516,12 @@ static u32 calculate_control(void)
 	 * the PCI Firmware Spec, r3.2, sec 4.5.1, table 4-5,
 	 * OSC_PCI_EXPRESS_DPC_CONTROL indicates the OS supports both DPC
 	 * and EDR.  EDR is always built with DPC on ACPI systems.
+	 *
+	 * PCI Firmware r3.3, sec 4.5.2.4, requires the OS to request AER
+	 * control while requesting DPC control.
 	 */
-	if (IS_ENABLED(CONFIG_PCIE_DPC))
+	if (IS_ENABLED(CONFIG_PCIE_DPC) &&
+	    (control & OSC_PCI_EXPRESS_AER_CONTROL))
 		control |= OSC_PCI_EXPRESS_DPC_CONTROL;
 
 	return control;
-- 
2.43.0


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

* [PATCH 4/4] PCI/portdrv: Bind DPC service based on host_bridge->native_dpc
  2026-10-07 16:58 [PATCH 0/4] PCI/DPC: Decide DPC ownership with host_bridge->native_dpc Kuppuswamy Sathyanarayanan
                   ` (2 preceding siblings ...)
  2026-10-07 16:58 ` [PATCH 3/4] PCI/ACPI: Request DPC control only together with AER control Kuppuswamy Sathyanarayanan
@ 2026-10-07 16:58 ` Kuppuswamy Sathyanarayanan
  3 siblings, 0 replies; 5+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-10-07 16:58 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rafael J . Wysocki, Lukas Wunner, Mahesh J Salgaonkar,
	Oliver O'Halloran, Len Brown, linux-pci, linux-acpi,
	linux-kernel

get_port_device_capability() binds the DPC service if the port has a DPC
capability and either "pcie_ports=dpc-native" was given or the OS
controls AER.  This repeats decisions that are already made elsewhere.
It also ignores host_bridge->native_dpc, which is meant to say whether
the OS owns DPC.

Make host_bridge->native_dpc the single decider:

  - In acpi_pci_root_create(), assume DPC control whenever _OSC grants
    AER control.  PCI Firmware r3.3, sec 4.5.2.4, requires platforms to
    retain AER if they retain DPC.  Put the other way, firmware that
    grants AER does not keep DPC.  PCIe r7.0 sec 6.2.11 recommends that
    the OS link control of DPC to control of AER.  Commit 97ca178c899d
    ("PCI/DPC: Allow DPC on all Downstream Ports when OS controls AER")
    relied on this link.  Keeping it means DPC still works with firmware
    that predates the _OSC DPC control bit.  Such firmware grants AER but
    masks DPC.  The OS cannot tell such firmware from firmware that
    retains DPC on purpose, so log a message when it assumes DPC control
    that _OSC did not grant.  Only do this if the OS requested DPC
    control, i.e., if CONFIG_PCIE_DPC is enabled.

  - "pcie_ports=native" and "pcie_ports=dpc-native" are already folded
    into the _OSC control mask, so they are reflected in native_dpc.

Then bind the DPC service if the port has a DPC capability and
host_bridge->native_dpc is set.

The only change in behavior is for firmware that grants DPC control but
retains AER control.  PCI Firmware r3.3, sec 4.5.2.4, does not forbid
this.  The OS now uses DPC there because firmware granted it.  With
Lukas's series, the DPC driver no longer depends on the AER driver.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
 drivers/acpi/pci_root.c    | 16 ++++++++++++++++
 drivers/pci/pcie/portdrv.c |  6 +-----
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5c674d5b6bb8..b380b6d8874d 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -1056,6 +1056,22 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	ctrl = root->osc_control_set;
 	ext_ctrl = root->osc_ext_control_set;
 
+	/*
+	 * PCI Firmware r3.3, sec 4.5.2.4, requires platforms to retain AER
+	 * if they retain DPC.  Put the other way, firmware that grants AER
+	 * does not keep DPC.  PCIe r7.0 sec 6.2.11 recommends that the OS
+	 * link control of DPC to control of AER.  Firmware that predates
+	 * the _OSC DPC control bit grants AER without DPC, so assume control
+	 * of DPC whenever we control AER.
+	 */
+	if (IS_ENABLED(CONFIG_PCIE_DPC) &&
+	    (ctrl & OSC_PCI_EXPRESS_AER_CONTROL) &&
+	    !(ctrl & OSC_PCI_EXPRESS_DPC_CONTROL)) {
+		decode_osc_control(root, "OS assuming control (AER granted) of",
+				   OSC_PCI_EXPRESS_DPC_CONTROL);
+		ctrl |= OSC_PCI_EXPRESS_DPC_CONTROL;
+	}
+
 	/*
 	 * If the user specified "pcie_ports=native", use the PCIe port
 	 * services regardless of what _OSC says, i.e., proceed as though the
diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index b77680fd3b75..f1beb440a3dc 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -258,12 +258,8 @@ static int get_port_device_capability(struct pci_dev *dev)
 		pcie_pme_interrupt_enable(dev, false);
 	}
 
-	/*
-	 * With dpc-native, allow Linux to use DPC even if it doesn't have
-	 * permission to use AER.
-	 */
 	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC) &&
-	    (pcie_ports_dpc_native || host->native_aer))
+	    host->native_dpc)
 		services |= PCIE_PORT_SERVICE_DPC;
 
 	/* Enable bandwidth control if more than one speed is supported. */
-- 
2.43.0


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

end of thread, other threads:[~2026-10-07 16:58 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-07 16:58 [PATCH 0/4] PCI/DPC: Decide DPC ownership with host_bridge->native_dpc Kuppuswamy Sathyanarayanan
2026-10-07 16:58 ` [PATCH 1/4] PCI/EDR: Remove CONFIG_PCIE_EDR Kuppuswamy Sathyanarayanan
2026-10-07 16:58 ` [PATCH 2/4] PCI/portdrv: Don't require AER to bind DPC service Kuppuswamy Sathyanarayanan
2026-10-07 16:58 ` [PATCH 3/4] PCI/ACPI: Request DPC control only together with AER control Kuppuswamy Sathyanarayanan
2026-10-07 16:58 ` [PATCH 4/4] PCI/portdrv: Bind DPC service based on host_bridge->native_dpc Kuppuswamy Sathyanarayanan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®