summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2016-10-28 10:52:06 +0200
committerBjorn Helgaas <bhelgaas@google.com>2016-11-18 01:43:49 +0100
commit738a7edbfc7b623e276686dead046c9f3aae6b2e (patch)
treee3abc850064b58a1c32682189ec34be25b8deefc
parentUSB: UHCI: report non-PME wakeup signalling for Intel hardware (diff)
downloadlinux-738a7edbfc7b623e276686dead046c9f3aae6b2e.tar.xz
linux-738a7edbfc7b623e276686dead046c9f3aae6b2e.zip
PCI: Don't acquire ref on parent in pci_bridge_d3_update()
This function is always called with an existing pci_dev struct, which holds a reference on the pci_bus struct it resides on, which in turn holds a reference on pci_bus->bridge, which is the pci_dev's parent. Hence there's no need to acquire an additional ref on the parent. More specifically, the pci_dev exists until pci_destroy_dev() drops the final reference on it, so all calls to pci_bridge_d3_update() must be finished before that. It is arguably the caller's responsibility to ensure that it doesn't call pci_bridge_d3_update() with a pci_dev that might suddenly disappear, but in any case the existing callers are all safe: - The call in pci_destroy_dev() happens before the call to put_device(). - The call in pci_bus_add_device() is synchronized with pci_destroy_dev() using pci_lock_rescan_remove(). - The calls to pci_d3cold_disable() from the xhci and nouveau drivers are safe because a ref on the pci_dev is held as long as it's bound to a driver. - The calls to pci_d3cold_enable() / pci_d3cold_disable() when modifying the sysfs "d3cold_allowed" entry are also safe because kernfs_drain() waits for existing sysfs users to finish before removing the entry, and pci_destroy_dev() is called way after that. No functional change intended. Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/pci/pci.c3
1 files changed, 0 insertions, 3 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index eda6a7cf0e54..5d6f2970fd6f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2296,7 +2296,6 @@ static void pci_bridge_d3_update(struct pci_dev *dev, bool remove)
if (!bridge || !pci_bridge_d3_possible(bridge))
return;
- pci_dev_get(bridge);
/*
* If the device is removed we do not care about its D3cold
* capabilities.
@@ -2318,8 +2317,6 @@ static void pci_bridge_d3_update(struct pci_dev *dev, bool remove)
/* Propagate change to upstream bridges */
pci_bridge_d3_update(bridge, false);
}
-
- pci_dev_put(bridge);
}
/**