linux/drivers/pci/hotplug
Bjorn Helgaas f652e7d291 PCI: shpchp: Use per-slot workqueues to avoid deadlock
When we have an SHPC-capable bridge with a second SHPC-capable bridge
below it, pushing the upstream bridge's attention button causes a
deadlock.

The deadlock happens because we use the shpchp_wq workqueue to run
shpchp_pushbutton_thread(), which uses shpchp_disable_slot() to remove
devices below the upstream bridge.  When we remove the downstream bridge,
we call shpc_remove(), the shpchp driver's .remove() method.  That calls
flush_workqueue(shpchp_wq), which deadlocks because the
shpchp_pushbutton_thread() work item is still running.

This patch avoids the deadlock by creating a workqueue for every slot
and removing the single shared workqueue.

Here's the call path that leads to the deadlock:

  shpchp_queue_pushbutton_work
    queue_work(shpchp_wq)		# shpchp_pushbutton_thread
    ...

  shpchp_pushbutton_thread
    shpchp_disable_slot
      remove_board
        shpchp_unconfigure_device
          pci_stop_and_remove_bus_device
            ...
              shpc_remove		# shpchp driver .remove method
                hpc_release_ctlr
                  cleanup_slots
                    flush_workqueue(shpchp_wq)

This change is based on code inspection, since we don't have hardware
with this topology.

Based-on-patch-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: stable@vger.kernel.org
2013-01-14 10:23:22 -07:00
..
acpi_pcihp.c module_param: make bool parameters really bool (drivers & misc) 2012-01-13 09:32:20 +10:30
acpiphp.h PCI: acpiphp: merge acpiphp_debug and debug 2012-07-10 17:02:37 -06:00
acpiphp_core.c PCI: acpiphp: merge acpiphp_debug and debug 2012-07-10 17:02:37 -06:00
acpiphp_glue.c Merge branch 'pci/jiang-acpiphp' into next 2012-09-24 16:36:48 -06:00
acpiphp_ibm.c module_param: make bool parameters really bool (drivers & misc) 2012-01-13 09:32:20 +10:30
cpci_hotplug.h
cpci_hotplug_core.c PCI: hotplug: ensure a consistent return value in error case 2012-07-16 09:25:56 -06:00
cpci_hotplug_pci.c PCI: cpci_hotplug: use generic pci_hp_add_bridge() 2012-06-13 15:42:26 -06:00
cpcihp_generic.c PCI/cpcihp: Use hotplug-safe pci_get_domain_bus_and_slot() 2012-09-12 14:13:59 -06:00
cpcihp_zt5550.c PCI: Remove __dev* markings 2012-11-28 13:16:47 -08:00
cpcihp_zt5550.h
cpqphp.h PCI: Make current and maximum bus speeds part of the PCI core 2010-02-22 16:15:17 -08:00
cpqphp_core.c PCI: hotplug: ensure a consistent return value in error case 2012-07-16 09:25:56 -06:00
cpqphp_ctrl.c PCI: cpqphp: Remove unreachable path 2012-09-10 16:45:41 -06:00
cpqphp_nvram.c
cpqphp_nvram.h
cpqphp_pci.c PCI: cpqhp: use generic pci_hp_add_bridge() 2012-06-13 15:42:26 -06:00
cpqphp_sysfs.c drivers: autoconvert trivial BKL users to private mutex 2010-10-05 15:01:04 +02:00
ibmphp.h
ibmphp_core.c PCI changes for the 3.6 merge window: 2012-07-24 16:17:07 -07:00
ibmphp_ebda.c pci: hotplug: Fix typo in pci 2012-07-24 12:59:30 +02:00
ibmphp_hpc.c PCI hotplug: ibmphp-hpc: semaphore cleanup 2010-10-15 13:09:48 -07:00
ibmphp_pci.c pci: hotplug: Fix typo in pci 2012-07-24 12:59:30 +02:00
ibmphp_res.c ibmphp: Rename add_range() to add_bus_range() to avoid conflict 2010-02-10 17:45:09 -08:00
Kconfig s390/pci: PCI hotplug support via SCLP 2012-11-30 17:47:25 +01:00
Makefile s390/pci: PCI hotplug support via SCLP 2012-11-30 17:47:25 +01:00
pci_hotplug_core.c module_param: make bool parameters really bool (drivers & misc) 2012-01-13 09:32:20 +10:30
pciehp.h PCI: pciehp: Use per-slot workqueues to avoid deadlock 2013-01-12 13:56:33 -07:00
pciehp_acpi.c PCI/pciehp: Use PCI Express Capability accessors 2012-08-23 10:11:11 -06:00
pciehp_core.c PCI: pciehp: Use per-slot workqueues to avoid deadlock 2013-01-12 13:56:33 -07:00
pciehp_ctrl.c PCI: pciehp: Use per-slot workqueues to avoid deadlock 2013-01-12 13:56:33 -07:00
pciehp_hpc.c PCI: pciehp: Use per-slot workqueues to avoid deadlock 2013-01-12 13:56:33 -07:00
pciehp_pci.c PCI: pciehp: use generic pci_hp_add_bridge() 2012-06-13 15:42:26 -06:00
pcihp_skeleton.c PCI: hotplug: ensure a consistent return value in error case 2012-07-16 09:25:56 -06:00
pcihp_slot.c PCI/hotplug: Use PCI Express Capability accessors 2012-08-23 10:11:11 -06:00
rpadlpar.h
rpadlpar_core.c powerpc/eeh: Remove EEH PE for normal PCI hotplug 2012-09-18 15:32:23 +10:00
rpadlpar_sysfs.c
rpaphp.h module_param: make bool parameters really bool (drivers & misc) 2012-01-13 09:32:20 +10:30
rpaphp_core.c module_param: make bool parameters really bool (drivers & misc) 2012-01-13 09:32:20 +10:30
rpaphp_pci.c
rpaphp_slot.c headers: kobject.h redux 2011-01-10 08:51:44 -08:00
s390_pci_hpc.c s390/pci: PCI hotplug support via SCLP 2012-11-30 17:47:25 +01:00
sgi_hotplug.c PCI: sgihp: use generic pci_hp_add_bridge() 2012-06-13 15:42:27 -06:00
shpchp.h PCI: shpchp: Use per-slot workqueues to avoid deadlock 2013-01-14 10:23:22 -07:00
shpchp_core.c PCI: shpchp: Use per-slot workqueues to avoid deadlock 2013-01-14 10:23:22 -07:00
shpchp_ctrl.c PCI: shpchp: Use per-slot workqueues to avoid deadlock 2013-01-14 10:23:22 -07:00
shpchp_hpc.c PCI hotplug: shpchp: don't blindly claim non-AMD 0x7450 device IDs 2011-11-14 09:43:14 -08:00
shpchp_pci.c PCI: shpchp: use generic pci_hp_add_bridge() 2012-06-13 15:42:26 -06:00
shpchp_sysfs.c PCI: replace struct pci_bus secondary/subordinate with busn_res 2012-06-13 15:42:22 -06:00