On Wed, Jul 01, 2020 at 09:53:51AM +0800, Yicong Yang wrote: > > static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev) > > { > > - struct pci_dev *bridge = pci_upstream_bridge(dev); > > - > > - while (bridge) { > > - if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT) > > - return bridge; > > - bridge = pci_upstream_bridge(bridge); > > + while (dev) { > > + if (pci_is_pcie(dev) && > > + pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) > > + return dev; > > + dev = pci_upstream_bridge(dev); > > } > > > > We may have some problems here, as after pcie_find_root_port() called, *dev will > be either root port or NULL but users may want it unchanged. One such usage is > in acpi_pci_bridge_d3(), drivers/pci/pci-acpi.c, *dev is used as origin > after called this. > > So we should use a temporary point to *dev rather than directly modify it. dev is already a copy of what is passed by the caller so it does not matter if it gets changed here. You would need to pass it through struct pci_dev **dev in order to modify the passed pointer.