FAILED: patch "[PATCH] PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable" failed to apply to 5.10-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 6cff20ce3b92ffbf2fc5eb9e5a030b3672aa414a
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025081512-refresh-safely-eef5@gregkh' --subject-prefix 'PATCH 5.10.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 6cff20ce3b92ffbf2fc5eb9e5a030b3672aa414a Mon Sep 17 00:00:00 2001
From: Lukas Wunner <[email protected]>
Date: Sun, 13 Jul 2025 16:31:01 +0200
Subject: [PATCH] PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable
ports
pci_bridge_d3_possible() is called from both pcie_portdrv_probe() and pcie_portdrv_remove() to determine whether runtime power management shall be enabled (on probe) or disabled (on remove) on a PCIe port.
The underlying assumption is that pci_bridge_d3_possible() always returns the same value, else a runtime PM reference imbalance would occur. That assumption is not given if the PCIe port is inaccessible on remove due to
hot-unplug: pci_bridge_d3_possible() calls pciehp_is_native(), which accesses Config Space to determine whether the port is Hot-Plug Capable. An inaccessible port returns "all ones", which is converted to "all zeroes" by pcie_capability_read_dword(). Hence the port no longer seems Hot-Plug Capable on remove even though it was on probe.
The resulting runtime PM ref imbalance causes warning messages such as:
pcieport 0000:02:04.0: Runtime PM usage count underflow!
Avoid the Config Space access (and thus the runtime PM ref imbalance) by caching the Hot-Plug Capable bit in struct pci_dev.
The struct already contains an "is_hotplug_bridge" flag, which however is not only set on Hot-Plug Capable PCIe ports, but also Conventional PCI Hot-Plug bridges and ACPI slots. The flag identifies bridges which are allocated additional MMIO and bus number resources to allow for hierarchy expansion.
The kernel is somewhat sloppily using "is_hotplug_bridge" in a number of places to identify Hot-Plug Capable PCIe ports, even though the flag encompasses other devices. Subsequent commits replace these occurrences with the new flag to clearly delineate Hot-Plug Capable PCIe ports from other kinds of hotplug bridges.
Document the existing "is_hotplug_bridge" and the new "is_pciehp" flag and document the (non-obvious) requirement that pci_bridge_d3_possible() always returns the same value across the entire lifetime of a bridge, including its hot-removal.
drivers/pci/pci-acpi.c +1 -3
@@ -816,13 +816,11 @@ int pci_acpi_program_hp_params(struct pci_dev *dev)bool pciehp_is_native (struct pci_dev *bridge) {const struct pci_host_bridge *host; -u32 slot_cap;if (!IS_ENABLED (CONFIG_HOTPLUG_PCI_PCIE ))return false; -pcie_capability_read_dword (bridge,PCI_EXP_SLTCAP , &slot_cap); -if (!(slot_cap &PCI_EXP_SLTCAP_HPC )) +if (!bridge->is_pciehp)return false;if (pcie_ports_native)
drivers/pci/pci.c +5 -1
@@ -3030,8 +3030,12 @@ static const struct dmi_system_id bridge_d3_blacklist[] = {* pci_bridge_d3_possible - Is it possible to put the bridge into D3 * @bridge: Bridge to check * -* This function checks if it is possible to move the bridge to D3. * Currently we only allow D3 for some PCIe ports and for Thunderbolt. +* +* Return: Whether it is possible to move the bridge to D3. +* +* The return value is guaranteed to be constant across the entire lifetime +* of the bridge, including its hot-removal. */ bool pci_bridge_d3_possible (struct pci_dev *bridge) {
drivers/pci/probe.c +1 -1
@@ -1678,7 +1678,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)pcie_capability_read_dword (pdev,PCI_EXP_SLTCAP , ®32);if (reg32 &PCI_EXP_SLTCAP_HPC ) - pdev->is_hotplug_bridge =1 ; + pdev->is_hotplug_bridge = pdev->is_pciehp =1 ; }static void set_pcie_thunderbolt (struct pci_dev *dev)
include/linux/pci.h +6 -0
@@ -328,6 +328,11 @@ struct rcec_ea;* determined (e.g., for Root Complex Integrated * Endpoints without the relevant Capability * Registers). +* @is_hotplug_bridge: Hotplug bridge of any kind (e.g. PCIe Hot-Plug Capable, +* Conventional PCI Hot-Plug, ACPI slot). +* Such bridges are allocated additional MMIO and bus +* number resources to allow for hierarchy expansion. +* @is_pciehp: PCIe Hot-Plug Capable bridge. */ struct pci_dev {struct list_head bus_list;/* Node in per-bus list */
@@ -451,6 +456,7 @@ struct pci_dev { unsigned int is_physfn:1; unsigned int is_virtfn:1; unsigned int is_hotplug_bridge:1; + unsigned int is_pciehp:1; unsigned int shpc_managed:1; /* SHPC owned by shpchp */ unsigned int is_thunderbolt:1; /* Thunderbolt controller *//*
Sasha Levin
maintainerPATCH 1/1 PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports
From: Lukas Wunner <[email protected]>
[ Upstream commit 6cff20ce3b92ffbf2fc5eb9e5a030b3672aa414a ]
pci_bridge_d3_possible() is called from both pcie_portdrv_probe() and pcie_portdrv_remove() to determine whether runtime power management shall be enabled (on probe) or disabled (on remove) on a PCIe port.
The underlying assumption is that pci_bridge_d3_possible() always returns the same value, else a runtime PM reference imbalance would occur. That assumption is not given if the PCIe port is inaccessible on remove due to
hot-unplug: pci_bridge_d3_possible() calls pciehp_is_native(), which accesses Config Space to determine whether the port is Hot-Plug Capable. An inaccessible port returns "all ones", which is converted to "all zeroes" by pcie_capability_read_dword(). Hence the port no longer seems Hot-Plug Capable on remove even though it was on probe.
The resulting runtime PM ref imbalance causes warning messages such as:
pcieport 0000:02:04.0: Runtime PM usage count underflow!
Avoid the Config Space access (and thus the runtime PM ref imbalance) by caching the Hot-Plug Capable bit in struct pci_dev.
The struct already contains an "is_hotplug_bridge" flag, which however is not only set on Hot-Plug Capable PCIe ports, but also Conventional PCI Hot-Plug bridges and ACPI slots. The flag identifies bridges which are allocated additional MMIO and bus number resources to allow for hierarchy expansion.
The kernel is somewhat sloppily using "is_hotplug_bridge" in a number of places to identify Hot-Plug Capable PCIe ports, even though the flag encompasses other devices. Subsequent commits replace these occurrences with the new flag to clearly delineate Hot-Plug Capable PCIe ports from other kinds of hotplug bridges.
Document the existing "is_hotplug_bridge" and the new "is_pciehp" flag and document the (non-obvious) requirement that pci_bridge_d3_possible() always returns the same value across the entire lifetime of a bridge, including its hot-removal.
--- drivers/pci/pci-acpi.c | 4 +--- drivers/pci/pci.c | 8 ++++++-- drivers/pci/probe.c | 2 +- include/linux/pci.h | 1 + 4 files changed, 9 insertions(+), 6 deletions(-)
drivers/pci/pci-acpi.c +1 -3
@@ -791,13 +791,11 @@ int pci_acpi_program_hp_params(struct pci_dev *dev)bool pciehp_is_native (struct pci_dev *bridge) {const struct pci_host_bridge *host; -u32 slot_cap;if (!IS_ENABLED (CONFIG_HOTPLUG_PCI_PCIE ))return false; -pcie_capability_read_dword (bridge,PCI_EXP_SLTCAP , &slot_cap); -if (!(slot_cap &PCI_EXP_SLTCAP_HPC )) +if (!bridge->is_pciehp)return false;if (pcie_ports_native)
drivers/pci/pci.c +6 -2
@@ -2860,8 +2860,12 @@ static const struct dmi_system_id bridge_d3_blacklist[] = {* pci_bridge_d3_possible - Is it possible to put the bridge into D3 * @bridge: Bridge to check * -* This function checks if it is possible to move the bridge to D3. -* Currently we only allow D3 for recent enough PCIe ports and Thunderbolt. +* Currently we only allow D3 for some PCIe ports and for Thunderbolt. +* +* Return: Whether it is possible to move the bridge to D3. +* +* The return value is guaranteed to be constant across the entire lifetime +* of the bridge, including its hot-removal. */ bool pci_bridge_d3_possible (struct pci_dev *bridge) {
drivers/pci/probe.c +1 -1
@@ -1582,7 +1582,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)pcie_capability_read_dword (pdev,PCI_EXP_SLTCAP , ®32);if (reg32 &PCI_EXP_SLTCAP_HPC ) - pdev->is_hotplug_bridge =1 ; + pdev->is_hotplug_bridge = pdev->is_pciehp =1 ; }static void set_pcie_thunderbolt (struct pci_dev *dev)
include/linux/pci.h +1 -0
@@ -439,6 +439,7 @@ struct pci_dev { unsigned int is_virtfn:1; unsigned int reset_fn:1; unsigned int is_hotplug_bridge:1; + unsigned int is_pciehp:1; unsigned int shpc_managed:1; /* SHPC owned by shpchp */ unsigned int is_thunderbolt:1; /* Thunderbolt controller *//*
Signature · 1 line
2.50.1