On Tue, Sep 15, 2026 at 1:56 PM Mario Limonciello <[email protected]> wrote: > > After "drm/amdgpu: Fix GPU PCIe link capability reporting" there are > now a few areas of walking topology. > > Use the cached GPU-side link device for ASPM queries and switch state > caching instead of walking the PCI topology independently in each path. > > Validate the internal downstream/upstream switch pair when initializing > the cached link devices so all consumers share the existing topology > checks. > > Signed-off-by: Mario Limonciello <[email protected]>
Acked-by: Alex Deucher <[email protected]> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 62 ++++++++-------------- > 1 file changed, 21 insertions(+), 41 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > index 0d277516fd55e..07121d4aed3dc 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > @@ -1353,31 +1353,6 @@ static bool amdgpu_device_aspm_support_quirk(struct > amdgpu_device *adev) > #endif > } > > -/* > - * Some dGPUs expose their display endpoint below an internal PCIe switch. > - * Use the switch upstream port to query the host-facing link. > - */ > -static struct pci_dev *amdgpu_device_get_aspm_pdev(struct amdgpu_device > *adev) > -{ > - struct pci_dev *swds, *swus; > - > - swds = pci_upstream_bridge(adev->pdev); > - if (!swds || > - (swds->vendor != PCI_VENDOR_ID_ATI && > - swds->vendor != PCI_VENDOR_ID_AMD) || > - pci_pcie_type(swds) != PCI_EXP_TYPE_DOWNSTREAM) > - return adev->pdev; > - > - swus = pci_upstream_bridge(swds); > - if (!swus || > - (swus->vendor != PCI_VENDOR_ID_ATI && > - swus->vendor != PCI_VENDOR_ID_AMD) || > - pci_pcie_type(swus) != PCI_EXP_TYPE_UPSTREAM) > - return adev->pdev; > - > - return swus; > -} > - > /** > * amdgpu_device_should_use_aspm - check if the device should program ASPM > * > @@ -1413,7 +1388,7 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device > *adev) > * the immediate upstream bridge. Use SWUS for dGPUs with an > * internal switch so that this is the host-facing link. > */ > - aspm_pdev = amdgpu_device_get_aspm_pdev(adev); > + aspm_pdev = adev->link_dev; > parent = pci_upstream_bridge(aspm_pdev); > if (!parent) { > dev_dbg(adev->dev, "ASPM: no upstream PCIe link for %s\n", > @@ -1961,15 +1936,26 @@ static void amdgpu_uid_fini(struct amdgpu_device > *adev) > > static void amdgpu_device_init_pcie_links(struct amdgpu_device *adev) > { > + struct pci_dev *swds, *swus; > + > adev->link_dev = adev->pdev; > adev->link_partner = pci_upstream_bridge(adev->link_dev); > > - /* Skip upstream/downstream switches internal to the dGPU. */ > - while (adev->link_partner && > - adev->link_partner->vendor == PCI_VENDOR_ID_ATI) { > - adev->link_dev = adev->link_partner; > - adev->link_partner = pci_upstream_bridge(adev->link_dev); > - } > + /* Skip an upstream/downstream switch internal to the dGPU. */ > + swds = adev->link_partner; > + if (!swds || swds->vendor != PCI_VENDOR_ID_ATI || > + pci_pcie_type(swds) != PCI_EXP_TYPE_DOWNSTREAM) > + return; > + > + swus = pci_upstream_bridge(swds); > + if (!swus || > + (swus->vendor != PCI_VENDOR_ID_ATI && > + swus->vendor != PCI_VENDOR_ID_AMD) || > + pci_pcie_type(swus) != PCI_EXP_TYPE_UPSTREAM) > + return; > + > + adev->link_dev = swus; > + adev->link_partner = pci_upstream_bridge(swus); > } > > /** > @@ -6428,16 +6414,10 @@ static void amdgpu_device_cache_switch_state(struct > amdgpu_device *adev) > struct pci_dev *swus, *swds; > int r; > > - swds = pci_upstream_bridge(adev->pdev); > - if (!swds || swds->vendor != PCI_VENDOR_ID_ATI || > - pci_pcie_type(swds) != PCI_EXP_TYPE_DOWNSTREAM) > - return; > - swus = pci_upstream_bridge(swds); > - if (!swus || > - (swus->vendor != PCI_VENDOR_ID_ATI && > - swus->vendor != PCI_VENDOR_ID_AMD) || > - pci_pcie_type(swus) != PCI_EXP_TYPE_UPSTREAM) > + swus = adev->link_dev != adev->pdev ? adev->link_dev : NULL; > + if (!swus) > return; > + swds = pci_upstream_bridge(adev->pdev); > > /* If already saved, return */ > if (adev->pcie_reset_ctx.swus) > -- > 2.43.0 >
