From: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Subject: [PATCH v2 2/2] powerpc: update pci_controller.refcount for PCI devices and buses
Date: Tue, 9 Aug 2016 21:44:04 -0300 [thread overview]
Message-ID: <1470789844-16401-3-git-send-email-mauricfo@linux.vnet.ibm.com> (raw)
In-Reply-To: <1470789844-16401-1-git-send-email-mauricfo@linux.vnet.ibm.com>
This patch employs the refcount in struct pci_controller to track
the references from PCI devices and buses (struct pci_dev/pci_bus).
In order to do that without modifying any PCI scan/probe approach
(e.g., PCI_PROBE_DEVTREE and PCI_PROBE_NORMAL), it leverages some
of the PCI arch-specific callback: pci_(add|release)_device() and
pci_(add|remove)_bus().
(a small change is required for PCI_PROBE_DEVTREE, which makes it
consistent with PCI_PROBE_NORMAL - the pci_dev should inherit the
parent pci_bus's phb pointer - see pci_setup_device() in probe.c)
This also has the advantage that locking for kref_(get|put)() is
satisfied by the 'pci_rescan_remove_lock' mutex, which is normal
practice for usage of the PCI subsystem - thus already in place.
More details added in comment on pcibios_release_device().
Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/pci-bridge.h | 4 ++--
arch/powerpc/kernel/pci-common.c | 25 +++++++++++++++++++++++++
arch/powerpc/kernel/pci-hotplug.c | 29 +++++++++++++++++++++++++++++
arch/powerpc/kernel/pci_of_scan.c | 1 +
4 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 6fde0a9..d10eee3 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -131,8 +131,8 @@ struct pci_controller {
/*
* Reference counting for the structures:
- * - TODO pci_dev
- * - TODO pci_bus
+ * - pci_dev
+ * - pci_bus
* - TODO pci_dn
* - TODO eeh_pe
* - TODO eeh_dev
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 29b37d3..c55e9c0 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1047,6 +1047,17 @@ static void pcibios_setup_device(struct pci_dev *dev)
int pcibios_add_device(struct pci_dev *dev)
{
+ struct pci_controller *phb = pci_bus_to_host(dev->bus);
+
+ pr_debug("PCI %s, pci_dev %p, phb %p\n", dev_name(&dev->dev), dev, phb);
+
+ if (!phb)
+ pr_warn("%s: PCI device %s has null PHB; refcount bug!",
+ __func__, dev_name(&dev->dev)); /* WARN_ON ahead */
+
+ /* locking: see comment on pcibios_release_device(). */
+ controller_get(phb);
+
/*
* We can only call pcibios_setup_device() after bus setup is complete,
* since some of the platform specific DMA setup code depends on it.
@@ -1062,6 +1073,20 @@ int pcibios_add_device(struct pci_dev *dev)
return 0;
}
+void pcibios_add_bus(struct pci_bus *bus)
+{
+ struct pci_controller *phb = pci_bus_to_host(bus);
+
+ pr_debug("PCI %s, pci_bus %p, phb %p\n", dev_name(&bus->dev), bus, phb);
+
+ if (!phb)
+ pr_warn("%s: PCI bus %s has null PHB; refcount bug!",
+ __func__, dev_name(&bus->dev)); /* WARN_ON ahead */
+
+ /* locking: see comment on pcibios_release_device(). */
+ controller_get(phb);
+}
+
void pcibios_setup_bus_devices(struct pci_bus *bus)
{
struct pci_dev *dev;
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index 2d71269..24d1a2a 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -55,15 +55,44 @@ EXPORT_SYMBOL_GPL(pci_find_bus_by_node);
* @dev: PCI device
*
* The function is called before releasing the indicated PCI device.
+ *
+ * The locking for kref_get() and kref_put() of the PHB/pci_controller
+ * in pcibios_(add|release)_device() and pcibios_(add|remove)_bus() is
+ * satisfied by the pci_rescan_remove_lock mutex (required for rescan/
+ * remove paths of PCI devices/buses; the scan path doesn't require it,
+ * as there is only addition of devices/buses - no removal at all.)
*/
void pcibios_release_device(struct pci_dev *dev)
{
struct pci_controller *phb = pci_bus_to_host(dev->bus);
+ pr_debug("PCI %s, pci_dev %p, phb %p\n", dev_name(&dev->dev), dev, phb);
+
eeh_remove_device(dev);
if (phb->controller_ops.release_device)
phb->controller_ops.release_device(dev);
+
+ if (unlikely(!phb))
+ pr_warn("%s: PCI device %s has null PHB; refcount bug!",
+ __func__, dev_name(&dev->dev)); /* WARN_ON ahead */
+
+ /* locking: see comment on pcibios_release_device(). */
+ controller_put(phb);
+}
+
+void pcibios_remove_bus(struct pci_bus *bus)
+{
+ struct pci_controller *phb = pci_bus_to_host(bus);
+
+ pr_debug("PCI %s, pci_bus %p, phb %p\n", dev_name(&bus->dev), bus, phb);
+
+ if (unlikely(!phb))
+ pr_warn("%s: PCI bus %s has null PHB; refcount bug!",
+ __func__, dev_name(&bus->dev)); /* WARN_ON ahead */
+
+ /* locking: see comment on pcibios_release_device(). */
+ controller_put(phb);
}
/**
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 526ac67..e6f0deb 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -142,6 +142,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
dev->devfn = devfn;
dev->multifunction = 0; /* maybe a lie? */
dev->needs_freset = 0; /* pcie fundamental reset required */
+ dev->sysdata = bus->sysdata; /* inherit bus's phb for phb->refcount */
set_pcie_port_type(dev);
pci_dev_assign_slot(dev);
--
1.8.3.1
next prev parent reply other threads:[~2016-08-10 0:44 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-10 0:44 [PATCH v2 0/2] powerpc: fix oops in pcibios_release_device() after pcibios_free_controller() Mauricio Faria de Oliveira
2016-08-10 0:44 ` [PATCH v2 1/2] powerpc: add refcount to struct pci_controller Mauricio Faria de Oliveira
2016-08-10 1:45 ` Andrew Donnellan
2016-08-10 12:03 ` Mauricio Faria de Oliveira
2016-08-10 13:53 ` Mauricio Faria de Oliveira
2016-08-10 21:46 ` Mauricio Faria de Oliveira
2016-08-10 0:44 ` Mauricio Faria de Oliveira [this message]
2016-08-10 3:35 ` [PATCH v2 2/2] powerpc: update pci_controller.refcount for PCI devices and buses Andrew Donnellan
2016-08-10 12:30 ` Mauricio Faria de Oliveira
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1470789844-16401-3-git-send-email-mauricfo@linux.vnet.ibm.com \
--to=mauricfo@linux.vnet.ibm.com \
--cc=linuxppc-dev@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).