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
acpiphp_core.c
acpiphp_glue.c
acpiphp_ibm.c
acpiphp.h
cpci_hotplug_core.c
cpci_hotplug_pci.c
cpci_hotplug.h
cpcihp_generic.c
cpcihp_zt5550.c
cpcihp_zt5550.h
cpqphp_core.c
cpqphp_ctrl.c
cpqphp_nvram.c
cpqphp_nvram.h
cpqphp_pci.c
cpqphp_sysfs.c
cpqphp.h
ibmphp_core.c
ibmphp_ebda.c
ibmphp_hpc.c
ibmphp_pci.c
ibmphp_res.c
ibmphp.h
Kconfig
Makefile
pci_hotplug_core.c
pciehp_acpi.c
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
pciehp.h PCI: pciehp: Use per-slot workqueues to avoid deadlock 2013-01-12 13:56:33 -07:00
pcihp_skeleton.c
pcihp_slot.c
rpadlpar_core.c
rpadlpar_sysfs.c
rpadlpar.h
rpaphp_core.c
rpaphp_pci.c
rpaphp_slot.c
rpaphp.h
s390_pci_hpc.c
sgi_hotplug.c
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
shpchp_pci.c
shpchp_sysfs.c
shpchp.h PCI: shpchp: Use per-slot workqueues to avoid deadlock 2013-01-14 10:23:22 -07:00