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
>

Reply via email to