linux/arch/powerpc/platforms/pseries
Mauricio Faria de Oliveira 2dd9c11b9d powerpc/pseries: use pci_host_bridge.release_fn() to kfree(phb)
This patch leverages 'struct pci_host_bridge' from the PCI subsystem
in order to free the pci_controller only after the last reference to
its devices is dropped (avoiding an oops in pcibios_release_device()
if the last reference is dropped after pcibios_free_controller()).

The patch relies on pci_host_bridge.release_fn() (and .release_data),
which is called automatically by the PCI subsystem when the root bus
is released (i.e., the last reference is dropped).  Those fields are
set via pci_set_host_bridge_release() (e.g. in the platform-specific
implementation of pcibios_root_bridge_prepare()).

It introduces the 'pcibios_free_controller_deferred()' .release_fn()
and it expects .release_data to hold a pointer to the pci_controller.

The function implictly calls 'pcibios_free_controller()', so an user
must *NOT* explicitly call it if using the new _deferred() callback.

The functionality is enabled for pseries (although it isn't platform
specific, and may be used by cxl).

Details on not-so-elegant design choices:

 - Use 'pci_host_bridge.release_data' field as pointer to associated
   'struct pci_controller' so *not* to 'pci_bus_to_host(bridge->bus)'
   in pcibios_free_controller_deferred().

   That's because pci_remove_root_bus() sets 'host_bridge->bus = NULL'
   (so, if the last reference is released after pci_remove_root_bus()
   runs, which eventually reaches pcibios_free_controller_deferred(),
   that would hit a null pointer dereference).

   The cxl/vphb.c code calls pci_remove_root_bus(), and the cxl folks
   are interested in this fix.

Test-case #1 (hold references)

  # ls -ld /sys/block/sd* | grep -m1 0021:01:00.0
  <...> /sys/block/sdaa -> ../devices/pci0021:01/0021:01:00.0/<...>

  # ls -ld /sys/block/sd* | grep -m1 0021:01:00.1
  <...> /sys/block/sdab -> ../devices/pci0021:01/0021:01:00.1/<...>

  # cat >/dev/sdaa & pid1=$!
  # cat >/dev/sdab & pid2=$!

  # drmgr -w 5 -d 1 -c phb -s 'PHB 33' -r
  Validating PHB DLPAR capability...yes.
  [  594.306719] pci_hp_remove_devices: PCI: Removing devices on bus 0021:01
  [  594.306738] pci_hp_remove_devices:    Removing 0021:01:00.0...
  ...
  [  598.236381] pci_hp_remove_devices:    Removing 0021:01:00.1...
  ...
  [  611.972077] pci_bus 0021:01: busn_res: [bus 01-ff] is released
  [  611.972140] rpadlpar_io: slot PHB 33 removed

  # kill -9 $pid1
  # kill -9 $pid2
  [  632.918088] pcibios_free_controller_deferred: domain 33, dynamic 1

Test-case #2 (don't hold references)

  # drmgr -w 5 -d 1 -c phb -s 'PHB 33' -r
  Validating PHB DLPAR capability...yes.
  [  916.357363] pci_hp_remove_devices: PCI: Removing devices on bus 0021:01
  [  916.357386] pci_hp_remove_devices:    Removing 0021:01:00.0...
  ...
  [  920.566527] pci_hp_remove_devices:    Removing 0021:01:00.1...
  ...
  [  933.955873] pci_bus 0021:01: busn_res: [bus 01-ff] is released
  [  933.955977] pcibios_free_controller_deferred: domain 33, dynamic 1
  [  933.955999] rpadlpar_io: slot PHB 33 removed

Suggested-By: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Tested-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> # cxl
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
2016-08-22 11:09:33 +10:00
..
cmm.c powerpc/pseries: Fix error return value in cmm_mem_going_offline() 2016-07-05 23:58:52 +10:00
dlpar.c powerpc/pseries: Use kernel hotplug queue for PowerVM hotplug events 2016-07-19 20:12:31 +10:00
dtl.c powerpc: Replace __get_cpu_var uses 2014-11-03 12:12:32 +11:00
eeh_pseries.c powerpc: Various typo fixes 2016-06-14 13:58:26 +10:00
event_sources.c powerpc/pseries: Remove MPIC from pseries event sources 2016-06-14 13:58:27 +10:00
firmware.c powerpc: Move FW feature probing out of pseries probe() 2016-07-21 18:56:13 +10:00
hotplug-cpu.c powerpc/pseries: Remove MPIC from pseries cpu hotplug 2016-06-14 13:58:27 +10:00
hotplug-memory.c powerpc: Fix unused function warning 'lmb_to_memblock' 2016-08-09 16:52:00 +10:00
hvCall_inst.c powerpc: Replace __get_cpu_var uses 2014-11-03 12:12:32 +11:00
hvCall.S powerpc, jump_label: Include linux/jump_label.h to get HAVE_JUMP_LABEL define 2015-04-09 09:40:29 +02:00
hvconsole.c powerpc: Fix misspellings in comments. 2016-03-01 19:27:20 +11:00
hvcserver.c powerpc/pseries/hvcserver: don't memset pi_buff if it is null 2015-10-09 08:03:03 +11:00
io_event_irq.c powerpc: Various typo fixes 2016-06-14 13:58:26 +10:00
iommu.c dma-mapping: use unsigned long for dma_attrs 2016-08-04 08:50:07 -04:00
Kconfig powerpc/pseries: Drop always true CONFIG_PSERIES_MSI 2015-10-15 20:31:56 +11:00
kexec.c powerpc/pseries: Remove MPIC from pseries kexec 2016-06-14 13:58:27 +10:00
lpar.c powerpc/mm: Rename hpte_init_lpar() and move the fallback to a header 2016-07-26 14:16:18 +10:00
lparcfg.c powerpc/mm/radix: Isolate hash table function from pseries guest code 2016-05-11 21:53:46 +10:00
Makefile powerpc/pseries: Drop always true CONFIG_PSERIES_MSI 2015-10-15 20:31:56 +11:00
mobility.c powerpc: Update of_remove_property() call sites to remove null checking 2016-05-11 21:54:04 +10:00
msi.c powerpc/pci: Export pci_traverse_device_nodes() 2016-05-11 21:54:25 +10:00
nvram.c powerpc/pseries: Remove unused pstore headers in nvram.c 2016-06-14 16:05:35 +10:00
of_helpers.c powerpc/pseries: Correct string length in pseries_of_derive_parent() 2015-10-28 12:08:18 +09:00
of_helpers.h powerpc/pseries: extract of_helpers module 2015-10-05 21:11:24 +11:00
offline_states.h powerpc/smp: soft-replugged CPUs must go back to start_secondary 2011-04-01 15:37:09 +11:00
pci_dlpar.c powerpc/pseries: use pci_host_bridge.release_fn() to kfree(phb) 2016-08-22 11:09:33 +10:00
pci.c powerpc/pseries: use pci_host_bridge.release_fn() to kfree(phb) 2016-08-22 11:09:33 +10:00
power.c powerpc/sparse: Include headers containing prototypes 2016-06-16 22:40:19 +10:00
pseries_energy.c powerpc/sparse: make some things static 2016-06-16 22:23:11 +10:00
pseries.h powerpc: Move FW feature probing out of pseries probe() 2016-07-21 18:56:13 +10:00
ras.c powerpc/pseries: Add support for hotplug interrupt source 2016-07-19 20:12:30 +10:00
reconfig.c powerpc: Update of_remove_property() call sites to remove null checking 2016-05-11 21:54:04 +10:00
rng.c powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_* 2015-07-23 19:52:03 +10:00
scanlog.c ppc: Clean up scanlog 2013-05-01 17:29:45 -04:00
setup.c powerpc: Get rid of ppc_md.init_early() 2016-07-21 19:07:26 +10:00
smp.c powerpc/pseries: Remove MPIC from pseries smp 2016-06-14 13:58:26 +10:00
suspend.c powerpc/pseries: Switch pseries drivers to use machine_xxx_initcall() 2014-07-28 14:11:26 +10:00