| From 6f963ec2d6bf2476a16799eece920acb2100ff1c Mon Sep 17 00:00:00 2001 |
| From: Ryan Grimm <grimm@linux.vnet.ibm.com> |
| Date: Wed, 28 Jan 2015 20:16:04 -0600 |
| Subject: cxl: Fix device_node reference counting |
| |
| From: Ryan Grimm <grimm@linux.vnet.ibm.com> |
| |
| commit 6f963ec2d6bf2476a16799eece920acb2100ff1c upstream. |
| |
| When unbinding and rebinding the driver on a system with a card in PHB0, this |
| error condition is reached after a few attempts: |
| |
| ERROR: Bad of_node_put() on /pciex@3fffe40000000 |
| CPU: 0 PID: 3040 Comm: bash Not tainted 3.18.0-rc3-12545-g3627ffe #152 |
| Call Trace: |
| [c000000721acb5c0] [c00000000086ef94] .dump_stack+0x84/0xb0 (unreliable) |
| [c000000721acb640] [c00000000073a0a8] .of_node_release+0xd8/0xe0 |
| [c000000721acb6d0] [c00000000044bc44] .kobject_release+0x74/0xe0 |
| [c000000721acb760] [c0000000007394fc] .of_node_put+0x1c/0x30 |
| [c000000721acb7d0] [c000000000545cd8] .cxl_probe+0x1a98/0x1d50 |
| [c000000721acb900] [c0000000004845a0] .local_pci_probe+0x40/0xc0 |
| [c000000721acb980] [c000000000484998] .pci_device_probe+0x128/0x170 |
| [c000000721acba30] [c00000000052400c] .driver_probe_device+0xac/0x2a0 |
| [c000000721acbad0] [c000000000522468] .bind_store+0x108/0x160 |
| [c000000721acbb70] [c000000000521448] .drv_attr_store+0x38/0x60 |
| [c000000721acbbe0] [c000000000293840] .sysfs_kf_write+0x60/0xa0 |
| [c000000721acbc50] [c000000000292500] .kernfs_fop_write+0x140/0x1d0 |
| [c000000721acbcf0] [c000000000208648] .vfs_write+0xd8/0x260 |
| [c000000721acbd90] [c000000000208b18] .SyS_write+0x58/0x100 |
| [c000000721acbe30] [c000000000009258] syscall_exit+0x0/0x98 |
| |
| We are missing a call to of_node_get(). pnv_pci_to_phb_node() should |
| call of_node_get() otherwise np's reference count isn't incremented and |
| it might go away. Rename pnv_pci_to_phb_node() to pnv_pci_get_phb_node() |
| so it's clear it calls of_node_get(). |
| |
| Signed-off-by: Ryan Grimm <grimm@linux.vnet.ibm.com> |
| Acked-by: Ian Munsie <imunsie@au1.ibm.com> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/powerpc/include/asm/pnv-pci.h | 2 +- |
| arch/powerpc/platforms/powernv/pci-ioda.c | 6 +++--- |
| drivers/misc/cxl/pci.c | 2 +- |
| 3 files changed, 5 insertions(+), 5 deletions(-) |
| |
| --- a/arch/powerpc/include/asm/pnv-pci.h |
| +++ b/arch/powerpc/include/asm/pnv-pci.h |
| @@ -19,7 +19,7 @@ int pnv_cxl_ioda_msi_setup(struct pci_de |
| int pnv_cxl_alloc_hwirqs(struct pci_dev *dev, int num); |
| void pnv_cxl_release_hwirqs(struct pci_dev *dev, int hwirq, int num); |
| int pnv_cxl_get_irq_count(struct pci_dev *dev); |
| -struct device_node *pnv_pci_to_phb_node(struct pci_dev *dev); |
| +struct device_node *pnv_pci_get_phb_node(struct pci_dev *dev); |
| |
| #ifdef CONFIG_CXL_BASE |
| int pnv_cxl_alloc_hwirq_ranges(struct cxl_irq_ranges *irqs, |
| --- a/arch/powerpc/platforms/powernv/pci-ioda.c |
| +++ b/arch/powerpc/platforms/powernv/pci-ioda.c |
| @@ -1460,13 +1460,13 @@ static void set_msi_irq_chip(struct pnv_ |
| |
| #ifdef CONFIG_CXL_BASE |
| |
| -struct device_node *pnv_pci_to_phb_node(struct pci_dev *dev) |
| +struct device_node *pnv_pci_get_phb_node(struct pci_dev *dev) |
| { |
| struct pci_controller *hose = pci_bus_to_host(dev->bus); |
| |
| - return hose->dn; |
| + return of_node_get(hose->dn); |
| } |
| -EXPORT_SYMBOL(pnv_pci_to_phb_node); |
| +EXPORT_SYMBOL(pnv_pci_get_phb_node); |
| |
| int pnv_phb_to_cxl(struct pci_dev *dev) |
| { |
| --- a/drivers/misc/cxl/pci.c |
| +++ b/drivers/misc/cxl/pci.c |
| @@ -316,7 +316,7 @@ static int init_implementation_adapter_r |
| u64 psl_dsnctl; |
| u64 chipid; |
| |
| - if (!(np = pnv_pci_to_phb_node(dev))) |
| + if (!(np = pnv_pci_get_phb_node(dev))) |
| return -ENODEV; |
| |
| while (np && !(prop = of_get_property(np, "ibm,chip-id", NULL))) |